Commit Graph

785 Commits

Author SHA1 Message Date
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
Michael Gottesman
b80c96a2e7 [+0 self] Teach SILGen how to avoid emitting extra rr pairs when emitting RValues with Nominal Types and Tuples.
Specifically this patch makes the following changes:

1. We properly propagate down the SGFContext of a tuple to its elements
when extracting from a tuple. There was a typo that caused us to use
data from the newly created default initialized copy instead of from the
actual SGFContext of the parent tuple.

2. If we are accessing a member ref of self in a guaranteed context:

  a. If self is a struct, regardless of whether or not the field is a
     var or a let we no longer emit a retain. This is b/c self in a
     guaranteed context is immutable. This implies even a var in the
     struct can not be reassigned to.

  b. If self is a class, if the field is a let, we no longer emit an
     extra retain.

This makes it so that the only rr traffic in IntTreeNode::find is in the
block of code where we return self.

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

 init() {} // not needed for -emit-silgen

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

One gets the same effect using a struct for IntTreeNode and a generic
box class, i.e.:

class Box<T> {
  let value: T
  init(newValue: T) { value = newValue }
}

class Kraken {}
struct IntTreeNode {
  let k : Kraken // Just to make IntTreeNode non-trivial for rr purposes.
  let left, right : Box<IntTreeNode>

  init() {} // not needed for -emit-silgen

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

There is more work that can be done here by applying similar logic to
enums, i.e. switching on self in an enum should not generate any rr
traffic over the switch. Also it seems that there are some places in SILGen
where isGuaranteedValid is not being propagated to SILGenFunction::emitLoad. But
that is for another day.

I am going to gather data over night and send an email to the list.

rdar://15729033

Swift SVN r27632
2015-04-23 10:10:43 +00:00
Chris Lattner
d9083d2e50 rework SGF::emitOptionalToOptional to keep loadable SILValue's as
registers instead of eagerly dumping them in memory and operating on
them by-address.  This avoids a lot of temporaries and traffic to 
manipulate them.

As part of this, add some new SGF::getOptionalNoneValue/getOptionalSomeValue
helper methods for forming loading optional values.

Many thanks to JoeG for helping with the abstraction difference change in
getOptionalSomeValue.



Swift SVN r27537
2015-04-21 22:54:08 +00:00
Chris Lattner
2fd563616e improve SILGen of RebindSelfInConstructorExpr in several ways:
- In the normal optional-to-optional init case, use
   "emitUncheckedGetOptionalValueFrom" instead of
   "emitCheckedGetOptionalValueFrom" since we have already
   checked to see if the optional is present.  This avoids a
   function call (that is mandatory inlined away) along with a ton
   of SIL that gets mandatory inlined in that shows an assertion 
   failure that can never fail.

 - Teach SGF::emitDoesOptionalHaveValue and
   SILGenFunction::emitUncheckedGetOptionalValueFrom to work with
   optionals in memory and optional values.

 - Based on this, stop dropping the optional self into a materialized
   temporary all the time.  Just use whatever we have (a value or the
   address of an address-only thing) and operate on it directly.

 - Use Cleanups.emitBlockForCleanups instead of emitting a block and
   using emitBranchAndCleanups.  This leads to cleaner code in SILGen
   and avoids emitting a dead block in the common case where there are
   no cleanups to perform.

Overall, these changes lead to better super.init calls in failable
inits, and more importantly enable understanding the output of -emit-sil 
on them :-)



Swift SVN r27477
2015-04-20 05:15:06 +00:00
John McCall
a67452c72c SILGen for throwing foreign errors out of @objc thunks.
Also, create a new file specifically for the foreign-error
code.

Swift SVN r27347
2015-04-16 05:16:54 +00:00
Doug Gregor
997136962e Always open existential types in the type checker.
Consistently open all references into existentials into
opened-existential archetypes within the constraint solver. Then,
during constraint application, use OpenExistentialExprs to record in
the AST where an existential is opened into an archetype, then use
that archetype throughout the subexpression. This simplifies the
overall representation, since we don't end up with a mix of operations
on existentials and operations on archetypes; it's all archetypes,
which tend to have better support down the line in SILGen already.

Start simplifying the code in SILGen by taking away the existential
paths that are no longer needed. I suspect there are more
simplifications to be had here.

The rules for placing OpenExistentialExprs are still a bit ad hoc;
this will get cleaned up later so that we can centralize that
information. Indeed, the one regression in the compiler-crasher suite
is because we're not closing out an open existential along an error
path.

Swift SVN r27230
2015-04-11 03:20:22 +00:00
Joe Groff
7be9c21c8b SILGen: Rework OpenExistentialExpr emission to better handle guaranteed contexts.
Try to emit the existential as a guaranteed value, and if we succeed, only +1 the bound opaque value if it's needed as a consumed value. This lets us avoid retaining or copying the existential if the existential can be produced and its contained value consumed at +0.

Swift SVN r27200
2015-04-10 02:58:57 +00:00
Doug Gregor
595fb8c94f Introduce lvalue open-existential expressions and start using them.
Place OpenExistentialExprs for references to lvalue subscripts or properties
(in protocol extensions) via existentials just outside of the member
or subscript reference, rather than far outside the expression. This
gives us a tighter bound on the open-existential expressions without
introducing the post-pass I was threatening.

OpenExistentialExprs just outside of lvalue member/subscript are
themselves lvalues. Resurrect John's OpenOpaqueExistentialComponent to
handle the opening of a (materialized) existential lvalues as an
lvalue path component. This has the nice effect of codifying the
formal access rules for opened existentials as well as handling inout
on opened existentials appropriately.

Big thanks to John for talking through the model with me and leaving
dead code around for me to use.

Swift SVN r27105
2015-04-07 23:22:05 +00:00
Doug Gregor
b8a7ebc20f Add LValue::dump(). NFC
Swift SVN r27104
2015-04-07 23:22:04 +00:00
Joe Groff
ad0d20c07a Fold "AbstractCC" into SILFunctionType::Representation.
These aren't really orthogonal concerns--you'll never have a @thick @cc(objc_method), or an @objc_block @cc(witness_method)--and we have gross decision trees all over the codebase that try to hopscotch between the subset of combinations that make sense. Stop the madness by eliminating AbstractCC and folding its states into SILFunctionTypeRepresentation. This cleans up a ton of code across the compiler.

I couldn't quite eliminate AbstractCC's information from AST function types, since SIL type lowering transiently created AnyFunctionTypes with AbstractCCs set, even though these never occur at the source level. To accommodate type lowering, allow AnyFunctionType::ExtInfo to carry a SILFunctionTypeRepresentation, and arrange for the overlapping representations to share raw values.

In order to avoid disturbing test output, AST and SILFunctionTypes are still printed and parsed using the existing @thin/@thick/@objc_block and @cc() attributes, which is kind of gross, but lets me stage in the real source-breaking change separately.

Swift SVN r27095
2015-04-07 21:59:39 +00:00
Doug Gregor
d3d20bbb4f Remove an unused LValue path component for opening opaque existentials.
NFC; this was dead code, and we're not going to be seeing these in
SILGen once the type checker is opening existentials.

Swift SVN r27084
2015-04-07 16:29:10 +00:00
Doug Gregor
441fb9856c Handle lvalue OpaqueValueExprs in SILGen.
Tests coming once Sema starts creating such entities.

Swift SVN r27066
2015-04-07 06:01:16 +00:00
Chris Lattner
95b7b4d5e4 rename CleanupLocation::getCleanupLocation -> CleanupLocation::get, NFC.
Swift SVN r26994
2015-04-04 22:56:01 +00:00
John McCall
dc4b8ff2c2 Incorporate an optional Clang type into AbstractionPattern.
This is necessary for correctly dealing with non-standard
ownership conventions in secondary positions, and it should
also help with non-injective type imports (like BOOL/_Bool).
But right now we aren't doing much with it.

Swift SVN r26954
2015-04-03 21:39:31 +00:00
John McCall
35b7db3ae1 Parsing support for error results from SILFunctionType.
Swift SVN r26566
2015-03-26 00:01:32 +00:00
Jordan Rose
d6bc8971c7 If imported calls return nil for __nonnull NSString *, pretend it was "".
The string version of r26479. There's a lot of backstory and justification
there, so just read that commit message again. The one addition for String
is that global NSString constants are loaded as String as well, so that
also has to go through the bridging code even though there's no function
call involved.

Finishes rdar://problem/19734621.

Swift SVN r26510
2015-03-25 01:16:45 +00:00
John McCall
ee4aa14703 Stop reordering blocks in SILBuilder::emitBlock.
This change permits SILGen to make smarter decisions about
block placement by keeping related blocks together instead
of always inserting to the end to the function.  The
flipside is that SILGen needs to be somewhat careful to
create blocks in the right order.  Counter-intuitively,
that order is the reverse of the order in which the blocks
should be laid out, since blocks created later will be
inserted before blocks created earlier.  Note, however,
that this produces the right results for recursive
emission.

To that end, adjust a couple of places in SILGen to
create blocks in properly nested order.

All of the block-order differences in the tests seem
to be desirable; several of them even had confused
comments wondering how on earth a block got injected
where it did.

Also, fix the implementation of SILBuilder::moveBlockTo,
and fix a latent bug in epilogue emission where epilogBB
was erased from its parent (deleting it) and then
queried multiple times (!).

Swift SVN r26428
2015-03-23 06:38:20 +00:00
Joe Groff
962a87f444 SIL: Rename address-only existential instructions to '{init,deinit,open}_existential_addr'.
For better consistency with other address-only instruction variants, and to open the door to new exciting existential representations (such as a refcounted boxed representation for ErrorType).

Swift SVN r25902
2015-03-09 23:55:31 +00:00
Michael Gottesman
77b2e21eb5 Move buildForwardingSubstitutions onto GenericParamList::getForwardingSubstitutions(). NFC.
Swift SVN r25358
2015-02-17 23:01:02 +00:00
Dmitri Hrybenko
61286f0260 Fix warnings produced by a newer version of Clang
Swift SVN r25257
2015-02-12 23:50:47 +00:00
Chris Lattner
9c7417edc2 fix <rdar://problem/19782264> Immutable, optional class members can't have their subproperties read from during init()
The problem here was that the _preconditionImplicitlyUnwrappedOptionalHasValue
compiler intrinsic was taking the optional/IUO argument as inout as a performance
optimization, but DI would reject it (in narrow cases, in inits) because the inout
argument looks like a mutation.  

We could rework this to take it as an @in argument or something, but it is better
to just define this problem away: the precondition doesn't actually care about the
optional, it is just testing its presence, which SILGen does all the time.  Have
SILGen open code the switch_enum and just have the stdlib provide a simpler
_diagnoseUnexpectedNilOptional() to produce the error message.

This avoids the problem completely and produces slightly better -O0 codegen.



Swift SVN r25254
2015-02-12 22:35:51 +00:00
Joe Groff
735bd354a5 SILGen: Remove !hasDifferentTypeOfRValue assertion from emitConversionFromSemanticValue.
We "convert" unowned to unowned without decaying to the semantic strong type when an unowned reference is captured by a nested closure. If we remove the assert, the codegen looks correct, and external projects walk this code path oblivious to the assertion.

Swift SVN r25248
2015-02-12 20:41:56 +00:00
Joe Groff
f1b97a1ead SILGen: Admit inout aliasing of polymorphic properties.
A stored property of a class may be overridden by a computed one, and a property requirement may be witnessed by a computed property, but rejecting inout aliasing in these cases isn't very helpful. Only reject cases that are definitely computed and will always behave incorrectly. Fixes rdar://problem/19633414.

Swift SVN r24986
2015-02-05 01:22:02 +00:00
John McCall
bf75beeb7a Begin formal accesses on l-value arguments immediately before
the call instead of during the formal evaluation of the argument.

This is the last major chunk of the semantic changes proposed
in the accessors document.  It has two purposes, both related
to the fact that it shortens the duration of the formal access.

First, the change isolates later evaluations (as long as they
precede the call) from the formal access, preventing them from
spuriously seeing unspecified behavior.  For example::

  foo(&array[0], bar(array))

Here the value passed to bar is a proper copy of 'array',
and if bar() decides to stash it aside, any modifications
to 'array[0]' made by foo() will not spontaneously appear
in the copy.  (In contrast, if something caused a copy of
'array' during foo()'s execution, that copy would violate
our formal access rules and would therefore be allowed to
have an arbitrary value at index 0.)

Second, when a mutating access uses a pinning addressor, the
change limits the amount of arbitrary code that falls between
the pin and unpin.  For example::

  array[0] += countNodes(subtree)

Previously, we would begin the access to array[0] before the
call to countNodes().  To eliminate the pin and unpin, the
optimizer would have needed to prove that countNodes didn't
access the same array.  With this change, the call is evaluated
first, and the access instead begins immediately before the call
to +=.  Since that operator is easily inlined, it becomes
straightforward to eliminate the pin/unpin.

A number of other changes got bundled up with this in ways that
are hard to tease apart.  In particular:

  - RValueSource is now ArgumentSource and can now store LValues.

  - It is now illegal to use emitRValue to emit an l-value.

  - Call argument emission is now smart enough to emit tuple
    shuffles itself, applying abstraction patterns in reverse
    through the shuffle.  It also evaluates varargs elements
    directly into the array.

  - AllowPlusZero has been split in two.  AllowImmediatePlusZero
    is useful when you are going to immediately consume the value;
    this is good enough to avoid copies/retains when reading a 'var'.
    AllowGuaranteedPlusZero is useful when you need a stronger
    guarantee, e.g. when arbitrary code might intervene between
    evaluation and use; it's still good enough to avoid copies
    from a 'let'.  The upshot is that we're now a lot smarter
    about generally avoiding retains on lets, but we've also
    gotten properly paranoid about calling non-mutating methods
    on vars.

    (Note that you can't necessarily avoid a copy when passing
    something in a var to an @in_guaranteed parameter!  You
    first have to prove that nothing can assign to the var during
    the call.  That should be easy as long as the var hasn't
    escaped, but that does need to be proven first, so we can't
    do it in SILGen.)

Swift SVN r24709
2015-01-24 13:05:46 +00:00
Joe Groff
a449948275 SILGen: Emit vtable thunks to handle optional variance.
If a subclass overrides methods with variance in the optionality of non-class-type members, emit a thunk to handle wrapping more optional parameters or results and force-unwrapping any IUO parameters made non-optional in the derived. For this to be useful, we need IRGen to finally pay attention to SILVTables, but this is a step on the way to fixing rdar://problem/19321484.

Swift SVN r24705
2015-01-24 05:21:26 +00:00
Chris Willmore
94bf316fc2 <rdar://problem/16937737> global NSString constants showing as NSString, not String
Import global variables of type NSString * as String instead of
NSString. Emit bridging code in SIL when such a variable is loaded.

Swift SVN r24495
2015-01-17 04:00:55 +00:00
John McCall
cae0f6e3db Add the ability for a owning addressor to return
a non-native owner.  This is required by Slice, which
will use an ObjC immutable array object as the owner
as long as all the elements are contiguous.

As part of this, I decided it was best to encode the
native requirement in the accessor names.  This makes
some of these accessors really long; we can revisit this
if we productize this feature.

Note that pinning addressors still require a native
owner, since pinning as a feature is specific to swift
refcounting.

Swift SVN r24420
2015-01-14 19:14:20 +00:00
John McCall
48f7a19d74 Enter a writeback scope before performing an assignment.
We need this in order to unpin at the correct moment.

Add an assertion that there's a scope active when pushing
an unpin writeback, as well as an assertion to ensure that
we never finish a function with writebacks active.

Swift SVN r24411
2015-01-14 02:17:27 +00:00
John McCall
3b89751b08 Merge the subscript r-value path with the l-value path.
Fixes a dumb bug where r-value subscripts would
unnecessarily emit their bases as ReadWrite.

Swift SVN r24410
2015-01-14 01:38:56 +00:00
John McCall
6a46350546 Bugfixes for the new addressor kinds.
Permit non-Ordinary accesses on references to functions,
with the semantics of devirtualizing the call if the
function is a class member.  This is important for
constructing direct call to addressors from synthesized
materializeForSet accessors: for one, it's more
performant, and for another, addressors do not currently
appear in v-tables.

Synthesize trivial accessors for addressed class members.
We weren't doing this at all before, and I'm still not
sure we're doing it right in all cases.  This is a mess.

Assorted other fixes.  The new addressor kinds seem
to work now.

Swift SVN r24393
2015-01-13 10:37:22 +00:00
John McCall
dc4431ebff Split addressors into unsafe, owning, and pinning variants.
Change all the existing addressors to the unsafe variant.

Update the addressor mangling to include the variant.

The addressor and mutable-addressor may be any of the
variants, independent of the choice for the other.

SILGen and code synthesis for the new variants is still
untested.

Swift SVN r24387
2015-01-13 03:09:16 +00:00
John McCall
f3dc58667d Improve the typing of materializeForSet callbacks to
use a thin function type.

We still need thin-function-to-RawPointer conversions
for generic code, but that's fixable with some sort of
partial_apply_thin_recoverable instruction.

Swift SVN r24364
2015-01-11 21:13:35 +00:00
Joe Groff
40d4710d61 SILGen: Fix overly restrictive assertion on lvalue-derived-from-rvalue bases.
The base value can be an address if it's any address-only type, not exclusively archetypes or existentials. Fixes nonmutating setters of address-only structs (rdar://problem/17841127), which I ran into while writing test cases for +0 self.

Swift SVN r24327
2015-01-09 21:41:08 +00:00
David Farler
3530e542ca Static class stored properties
rdar://problem/19422120

Allow static/class final stored properties to get through to the
mangled global property implementations.

Swift SVN r24303
2015-01-09 09:54:18 +00:00