Commit Graph

1246 Commits

Author SHA1 Message Date
Doug Gregor
f1be1ed572 Implement super mesage sends for @objc property and subscript getters/setters.
Fixes <rdar://problem/15933008>.


Swift SVN r13100
2014-01-29 07:45:53 +00:00
Chris Lattner
290a58494e Implement debug info for willset/didset, and teach dispatch to be non-virtual
to didset/will set since we don't drop these in the class vtable.


Swift SVN r13056
2014-01-28 06:33:31 +00:00
Joe Groff
b6108c0bc2 SILGen: Consume CallEmission parameters based on the interface type.
NFC, the logic here does not depend on generic context.

Swift SVN r13039
2014-01-28 02:46:33 +00:00
Chris Lattner
a945271aa8 Now that properties in protocols are always computed, and that StoredObjC
properties have accessors, we have an amazing property: everything that we
want to form a getter or setter for ... really has one! I suspect many things
can be simplified now, but the first on the chopping block is 
StorageDecl::getGetterType (and its three friends) which is now always exactly
just getGetter()->getType().



Swift SVN r12983
2014-01-27 06:17:28 +00:00
Chris Lattner
17d784a164 simplify code further. This avoids retain/releasing the base of a classbound protocol/existential.
No change in the stdlib.


Swift SVN r12878
2014-01-23 21:50:03 +00:00
Chris Lattner
c866b721d2 Remove the old "getExistentialOrArchetypeRValueAddress" hack for producing some
bases at +0, and use the new SGFContext::AllowPlusZero mechanism instead.  It
is more rigorous and general.  This cuts 34 lines out of the stdlib, deleting
temporary materializations from: Zip2.generate, and several methods from
Reverse and ReverseIndex.

Also:
 SILGenApply.cpp |   41 ++++-------------------------------------
 1 file changed, 4 insertions(+), 37 deletions(-)



Swift SVN r12875
2014-01-23 21:25:06 +00:00
Dave Zarzycki
6eba6ceeeb Zap accumlated unused variable warnings in non-assert builds
Swift SVN r12861
2014-01-23 08:11:37 +00:00
Chris Lattner
87fbce6a1a Progress on <rdar://problem/15867140> [string perf] member_ref_expr on an rvalue producing unnecessary retains/releases
- Remove my previous local hack.
- Add a new flag to SGFContext indicating that clients are ok with +0 rvalues.
- Teach emitRValueForPropertyLoad and emitRValueForDecl how to work with +0 rvalues.

This allows us to avoid retaining bases in arbitrarily nested struct rvalue
member_ref_expr's.  For example, this:

class SomeClass {}

struct AnotherStruct {
  var x : Int
  var c : SomeClass
}

struct StructMemberTest {
  var c1 : SomeClass, c2 : SomeClass
  var s : AnotherStruct

  func testRecursiveStruct() -> Int {
    return s.x
  }
}

used to compile to:

sil @_TFV1t16StructMemberTest19testRecursiveStructfS0_FT_Si : $@cc(method) @thin (@owned StructMemberTest) -> Int64 {
bb0(%0 : $StructMemberTest):
  debug_value %0 : $StructMemberTest  // let self // id: %1
  %2 = struct_extract %0 : $StructMemberTest, #s  // user: %3
  %3 = copy_value %2 : $AnotherStruct             // users: %5, %4
  %4 = struct_extract %3 : $AnotherStruct, #x     // user: %7
  destroy_value %3 : $AnotherStruct               // id: %5
  destroy_value %0 : $StructMemberTest            // id: %6
  return %4 : $Int64                              // id: %7
}

and now it compiles to:

sil @_TFV1t16StructMemberTest19testRecursiveStructfS0_FT_Si : $@cc(method) @thin (@owned StructMemberTest) -> Int64 {
bb0(%0 : $StructMemberTest):
  debug_value %0 : $StructMemberTest  // let self // id: %1
  %2 = struct_extract %0 : $StructMemberTest, #s  // user: %3
  %3 = struct_extract %2 : $AnotherStruct, #x     // user: %5
  destroy_value %0 : $StructMemberTest            // id: %4
  return %3 : $Int64                              // id: %5
}

There is more that can come from this, but it is a start.  This cuts out 50 retain/release pairs from the stdlib.



Swift SVN r12857
2014-01-23 06:54:02 +00:00
Dave Abrahams
d58caea0cd Revert "Zap accumlated warnings in non-assert builds"
This reverts r12850, which broke the build for me.

Swift SVN r12856
2014-01-23 06:47:29 +00:00
Dave Zarzycki
17eb84d9c6 Zap accumlated warnings in non-assert builds
Swift SVN r12850
2014-01-23 05:45:24 +00:00
Chris Lattner
3c60715902 fix two cases where SGFContext's were incorrectly passed down when of
the wrong type.  this was noticed by inspection, I don't have a testcase.


Swift SVN r12817
2014-01-22 23:48:05 +00:00
Chris Lattner
84f9919016 introduce a SGF::emitRValueAsSingleValue helper function to wrap a common
and repetitive pattern.


Swift SVN r12808
2014-01-22 22:51:55 +00:00
Chris Lattner
7ee9d7070e The 'ChildOfLoad' and 'Ungeneralized' forms of SGFContext are not used,
remove them.


Swift SVN r12797
2014-01-22 22:21:23 +00:00
Chris Lattner
c755b13aa0 update comments for the [attributes] -> @attributes syntax change.
Swift SVN r12795
2014-01-22 22:09:57 +00:00
Chris Lattner
7cd0f1739a A big part of handling address-only types is making sure that various
emission routines use the SGFContext passed in.  To help with this and
to help the handshake, add a new "isInContext()" representation to 
ManagedValue.  This makes the code producing and consuming these more
explicit.  NFC.


Swift SVN r12783
2014-01-22 21:31:44 +00:00
Chris Lattner
b457be6a9f SGF::emitLValueForDecl only works on VarDecls, make its prototype more specific
to reflect that.


Swift SVN r12753
2014-01-22 18:20:06 +00:00
Chris Lattner
a7b39c21f3 emitReferenceToDecl is serving two purposes: for VarDecls it
can often produce an lvalue, for everything else it produces an RValue.

Split it up a bit so that all of the lvalue cases are handled by 
emitLValueForDecl (which it calls).  This allows clients that only
expect an lvalue back to have a simpler path, and allows one that
wants to probe to see if something is an lvalue or not to be simpler.



Swift SVN r12715
2014-01-22 07:07:05 +00:00
Chris Lattner
07970706b7 tidy some comments, add an assertion that lvalues always
have isAddress() type.


Swift SVN r12711
2014-01-22 06:39:52 +00:00
Chris Lattner
63784ca41c remove the ManagedValue::Unmanaged marker, lets just use ManagedValue::forUnmanaged()
instead, which is shorter.  It is better to have one way to do things than two.


Swift SVN r12710
2014-01-22 06:26:34 +00:00
Chris Lattner
f7597fb25d improve comments on ManagedValue, eliminate the LValue_t enum marker
in favor of ManagedValue::forLValue.  NFC.


Swift SVN r12709
2014-01-22 06:16:36 +00:00
Chris Lattner
2ab1f29664 Use emitRValueForDecl in various places that expect an RValue, and
use emitReferenceToDecl when we expect an lvalue or rvalue.  This
makes the code more explicit and avoids duplicating the "emit a
load if emitReferenceToDecl returned an lvalue" logic.


Swift SVN r12603
2014-01-20 18:50:34 +00:00
Chris Lattner
f5b85341a1 Expand out the "isComputed" property in AbstractStorageDecl to be an enum
with two kinds, and some more specific predicates that clients can use.

The notion of 'computed or not' isn't specific enough for how properties
are accessed.  We already have problems with ObjC properties that are 
stored but usually accessed through getters and setters, and a bool here
isn't helping matters.

NFC.



Swift SVN r12593
2014-01-20 18:16:30 +00:00
Chris Lattner
22bced4c08 retype emitGetAccessor/emitSetAccessor to take an AbstractStorageDecl
instead of a ValueDecl (which is more specific).  This allows them to
use the more specific ASD::usesObjCGetterAndSetter() method instead
of SGM::requiresObjCDispatch.

To enable this, push AbstractStorageDecl through SILGenLValue's
GetterSetterComponent.


Swift SVN r12578
2014-01-20 16:00:48 +00:00
Joe Groff
0776c4b6b8 SIL: Reorient function type lowering toward interface types.
Lower types for SILDeclRefs from the interface types of their referents, dragging the old type along for the ride so we can still offer the context to clients that haven't been weaned off of it. Make SILFunctionType's interface types and generic signature independent arguments of its  Derive the context types of SILFunctionType from the interface types, instead of the other way around. Do a bunch of annoying inseparable work in the AST and IRGen to accommodate the switchover.

Swift SVN r12536
2014-01-18 19:42:02 +00:00
Chris Lattner
bb3c0d52dc Unfortunately, two conflated NFC patches:
1) Revert my change to give DeclContext a dump method, it confuses the debugger.
2) Refactor SILGen::requiresObjCPropertyEntryPoints out to 
   VarDecl::usesObjCGetterAndSetter.


Swift SVN r12526
2014-01-18 02:00:23 +00:00
Jordan Rose
11008f0ed1 Split diagnostics out into separate files.
Thanks to the way we've set up our diagnostics engine, there's not actually
a reason for /everything/ to get rebuilt when /one/ diagnostic changes.
I've split them up into five categories for now: Parse, Sema, SIL, IRGen,
and Frontend, plus a set of "Common" diagnostics that are used in multiple
areas of the compiler. We can massage this later.

No functionality change, but should speed up compile times!

Swift SVN r12438
2014-01-17 00:15:12 +00:00
Chris Lattner
c264d334fa teach SILGenApply about 'let' declarations, so that @autoclosure lets
get marked transparent the same way @autoclosure var's do.


Swift SVN r12368
2014-01-16 00:41:54 +00:00
John McCall
1ccf23487e Remove unnecessary ASTContext& argument from getOptionalObjectType().
Swift SVN r12344
2014-01-15 21:00:58 +00:00
Joe Groff
990212b1c6 SILGen: When applying the result function of a function, do not reabstract to the original callee's abstraction pattern.
We already reabstracted the result function to the substituted function type. Quick fix for <rdar://problem/15598596>.

Swift SVN r12307
2014-01-15 01:20:14 +00:00
Chris Lattner
c081e7ddb1 random comment cleanups.
Swift SVN r12133
2014-01-10 20:25:24 +00:00
Chris Lattner
373d0de766 Now that SILGen is in charge of temporary materialization (or not) we
can implement fun optimizations.  Here, we avoid materializing a
temporary copy for 'let' bases of protocol and archetype methods.
Consider:
protocol SimpleProtocol {
  func doSomethingGreat()
}

func testLetProtocolBases(let p : SimpleProtocol) {
  p.doSomethingGreat()
  p.doSomethingGreat()
}

before we produced:

sil @_TF1t20testLetProtocolBasesFT1pPS_14SimpleProtocol__T_ : $@thin (@in SimpleProtocol) -> () {
bb0(%0 : $*SimpleProtocol):
  %1 = alloc_stack $SimpleProtocol                // users: %7, %6, %4, %3, %2
  copy_addr %0 to [initialization] %1#1 : $*SimpleProtocol // id: %2
  %3 = project_existential %1#1 : $*SimpleProtocol to $*@sil_self SimpleProtocol // user: %5
  %4 = protocol_method %1#1 : $*SimpleProtocol, #SimpleProtocol.doSomethingGreat!1 : $@cc(witness_method) @callee_owned (@inout Self) -> () // user: %5
  %5 = apply %4(%3) : $@cc(witness_method) @callee_owned (@inout Self) -> ()
  destroy_addr %1#1 : $*SimpleProtocol            // id: %6
  dealloc_stack %1#0 : $*@local_storage SimpleProtocol // id: %7
  %8 = alloc_stack $SimpleProtocol                // users: %14, %13, %11, %10, %9
  copy_addr %0 to [initialization] %8#1 : $*SimpleProtocol // id: %9
  %10 = project_existential %8#1 : $*SimpleProtocol to $*@sil_self SimpleProtocol // user: %12
  %11 = protocol_method %8#1 : $*SimpleProtocol, #SimpleProtocol.doSomethingGreat!1 : $@cc(witness_method) @callee_owned (@inout Self) -> () // user: %12
  %12 = apply %11(%10) : $@cc(witness_method) @callee_owned (@inout Self) -> ()
  destroy_addr %8#1 : $*SimpleProtocol            // id: %13
  dealloc_stack %8#0 : $*@local_storage SimpleProtocol // id: %14
  destroy_addr %0 : $*SimpleProtocol              // id: %15
  %16 = tuple ()                                  // user: %17
  return %16 : $()                                // id: %17
}

now we produce the svelte:

sil @_TF1t20testLetProtocolBasesFT1pPS_14SimpleProtocol__T_ : $@thin (@in SimpleProtocol) -> () {
bb0(%0 : $*SimpleProtocol):
  %1 = project_existential %0 : $*SimpleProtocol to $*@sil_self SimpleProtocol // user: %3
  %2 = protocol_method %0 : $*SimpleProtocol, #SimpleProtocol.doSomethingGreat!1 : $@cc(witness_method) @callee_owned (@inout Self) -> () // user: %3
  %3 = apply %2(%1) : $@cc(witness_method) @callee_owned (@inout Self) -> ()
  %4 = project_existential %0 : $*SimpleProtocol to $*@sil_self SimpleProtocol // user: %6
  %5 = protocol_method %0 : $*SimpleProtocol, #SimpleProtocol.doSomethingGreat!1 : $@cc(witness_method) @callee_owned (@inout Self) -> () // user: %6
  %6 = apply %5(%4) : $@cc(witness_method) @callee_owned (@inout Self) -> ()
  destroy_addr %0 : $*SimpleProtocol              // id: %7
  %8 = tuple ()                                   // user: %9
  return %8 : $()                                 // id: %9
}

It turns out that 'var's were getting this optimization accidentally because the var
box had the single reference, but that it didn't work for 'let's.  It turns out that 
this optimization matters a lot when you enter the intersection of "required 
optimizations" that our string/array append implementation
imply: doing the extra copy defeats their "has one reference" optimizations. 

This also refactors some code into a shared place between archetypes and existentials.



Swift SVN r12131
2014-01-10 19:56:17 +00:00
Chris Lattner
f6a08290bc switch archetype bases over to the new world order where ArchetypeMemberRef
takes the archetype as an rvalue, not an lvalue.  This defines away the need
for MaterializeExpr at sema time, reusing the existing temporary mechanics in
SILGen.  This also opens future optimizations.


Swift SVN r12123
2014-01-10 17:41:38 +00:00
Chris Lattner
0013ceea39 Rework how existential member references (i.e., calls to protocol methods)
to non-@mutating methods work in the AST: now the base expression is 
always computed as an rvalue, instead of computing them as an lvalue.  The 
optimization that we were accidentally getting before is now explicitly 
modeled, and the non-optimized case is now handled by standard temporary 
emission in SILGen instead of with MaterializeExpr.  The upshot of this 
carefully choreographed step is that there is no change in generated code (!).

Archetype member references still need to be switched over to this new
scheme (at which point materializeexpr is dead), and the optimization 
needs to be replicated for 'let' bases (at which point arguments 
becoming 'let' is only gated on debug info).



Swift SVN r12120
2014-01-10 07:26:30 +00:00
Joe Groff
b2f0b90ba2 SIL: Switch to SILFunctionType interface types in easy-to-reach places.
In nongeneric contexts, or contexts where we only care about the indirectness of parameters or have already substituted the generic parameters for a function, the interface types are interchangeable, so just switch over.

Swift SVN r12044
2014-01-08 04:48:29 +00:00
Joe Groff
c47820ff3d Add a convenience method for reparenting a GenericParamList.
NFC.

Swift SVN r11995
2014-01-07 17:56:36 +00:00
Doug Gregor
1cf3bdbe8c Use objc_msgSendSuper[Stret] for foreign initializer delegation.
Introduce the SIL instruction peer_method, which references a method
in the given class or one of its superclasses (but not a subclass). It
IRGen's to objc_msgSendSuper[Stret] (vs. super_method IRGen'ing to
objc_msgSendSuper[Stret]2 for superclass lookup).

Use peer_method for initializer delegation to a foreign initializer
(i.e., an init-family method written in Objective-C) to close the
safety loophole introduced by initializer delegation in r11965. The
loophole still exists, but can only be triggered from Objective-C.

Teach definite initialization that peer_method really isn't a use of
self.



Swift SVN r11992
2014-01-07 17:33:41 +00:00
Joe Groff
44fb729830 SIL: Use only interface types in the verifier.
Treat the interface types of SILFunctionTypes as the canonical representation in the verifier. Do a bunch of supporting and annoyingly irreducible work to enable this:

- Stop trying to uncurry generic parameter lists during type lowering and preserve the structure of AST GenericParamLists. This makes mapping dependent types into contexts easier.
- Properly walk generic parameter lists at all depths when grooming substitution vectors for use with substGenericArgs interfaces.
- Reseat the generic parameter lists created for protocol_method results so that we don't expect the outer Self archetype to be unbound; it's provided by the extra data of the result.
- Hack SILFunctionType serialization never to use a decl reference when serializing its generic param list. When this happens, we get incorrect archetypes. This is a gross hack, but when we're able to jump all the way to interface types, it can go away.

Putting these ducks in a row nicely un-XFAILs TextFormatting.swift.

Swift SVN r11989
2014-01-07 06:50:20 +00:00
Doug Gregor
90f3b554ee Initializer delegation to a foreign initializer must go through class_method.
Initiializer delegation in Swift always calls a peer initializer
directly. However, there are no direct calls for methods defined in
Objective-C, so go through Objective-C's message send. This is a
potential safety hole, because we could end up in a subclass's
initializer.


Swift SVN r11965
2014-01-06 23:51:07 +00:00
Doug Gregor
c498a9fdb3 SIL generation for initializer delegation for structs and enums.
Much of the fun here comes from the need to delegate to the allocating
constructor for structs and enums (which have no initializing
constructors). The AST doesn't (and shouldn't) know about this, so
SILGen has to turn cope with the transformation.



Swift SVN r11949
2014-01-06 20:38:20 +00:00
Chris Lattner
dcd8581f6c Fix RValueEmitter::visitDeclRefExpr to do the right thing when SGFContext
specifies a destination to plop the loaded decl into.  This isn't actually
being used, just something I noticed in flight.


Swift SVN r11910
2014-01-04 21:11:29 +00:00
Chris Lattner
b61a6fd946 Rework AST and SILGen of properties and subscripts to take advantage of the new mutability model.
- Change the AST for get/set functions to take self @inout only when they 
  are @mutating.  Setters default to @mutating, but can be explicitly marked 
  @!mutating. Getters default to not mutating, but can be marked @mutating.  
  This causes self to follow.
- Change sema to handle semantic analysis of a.y (and subscripts) based on
  whether the computed type of a allows mutation (which is when 'a' is an 
  lvalue, or both the getter and setter are non-mutating).  When both of
  these conditions fail, 'a.y' has rvalue type, and is thus non-mutable.
- Rework silgen of lvalues to handle this: now properties and subscripts 
  can have rvalues as bases, which means that all the lvalue machinery needs 
  to be able to handle the full generality of base expressions (which is 
  what my recent patches have been paving the way towards).
- Rework silgen of rvalues to similarly handle rvalue bases.
- Rework silgen of both to handle the case where the AST has found a base
  expression that is an lvalue, but where only a non-mutating getter or
  setter is needed.  Right now, we just emit a load of the lvalue, but
  it would result in better code to not require the base be an lvalue at 
  all (todo).

The upshot of all of this is that we are doing *much* less AST-level 
materialization (MaterializeExpr goes down), we generate a lot better SIL
out of SILGen in many cases, and 'self' being an rvalue in properties and
subscripts means that we correctly reject code like the examples in
test/Sema/immutability.swift.



Swift SVN r11884
2014-01-04 04:27:51 +00:00
Dave Zarzycki
31d3c37141 Revert r11855: "simplify some code, managed value does the right thing for us here."
This was causing the tests to spin forever.

Swift SVN r11864
2014-01-03 19:37:44 +00:00
Chris Lattner
5b394f67f3 sink SILDeclRef's down into emitGetAccessor/emitSetAccessor, which are
the things that apparently care about it.  The LValue/RValue machinery is 
happy to pass around the VarDecl/SubscriptDecl for the entity being
referenced, and this simplifies things.


Swift SVN r11857
2014-01-03 07:19:40 +00:00
Chris Lattner
d40295fccd simplify some code, managed value does the right thing for us here.
Swift SVN r11855
2014-01-03 06:38:27 +00:00
Chris Lattner
7d9ae2f418 Use the power of ManagedValue to pass along +1 ownership of the base
receiver until something consumes it.  This means that something with
writeback (which invokes both the getter and setter) needs to copy the
managed value (since two things consume the +1), but that's what
ManagedValue is for.

Upshot of this is that we stop emitting redundant retain/release calls
in cases where writeback isn't needed.  For example:

class Foo {
  var x : Int { get: set: }
}

func test(let f : Foo, let i : Int) {
  f.x = i
}

used to silgen to:

sil @_TF1t4testFTCS_3FooSi_T_ : $@thin (@owned Foo, Int64) -> () {
bb0(%0 : $Foo, %1 : $Int64):
  strong_retain %0 : $Foo                         // id: %2
  strong_retain %0 : $Foo                         // id: %3
  // function_ref t.Foo.x.setter : swift.Int64
  %4 = function_ref @_TFC1t3Foos1xSi : $@cc(method) @thin (Int64, @owned Foo) -> () // user: %5
  %5 = apply %4(%1, %0) : $@cc(method) @thin (Int64, @owned Foo) -> ()
  strong_release %0 : $Foo                        // id: %6
  strong_release %0 : $Foo                        // id: %7
  %8 = tuple ()                                   // user: %9
  return %8 : $()                                 // id: %9
}

now it silgen's to:

sil @_TF1t4testFT1fCS_3Foo1iSi_T_ : $@thin (@owned Foo, Int64) -> () {
bb0(%0 : $Foo, %1 : $Int64):
  strong_retain %0 : $Foo                         // id: %2
  // function_ref t.Foo.x.setter : swift.Int64
  %3 = function_ref @_TFC1t3Foos1xSi : $@cc(method) @thin (Int64, @owned Foo) -> () // user: %4
  %4 = apply %3(%1, %0) : $@cc(method) @thin (Int64, @owned Foo) -> ()
  strong_release %0 : $Foo                        // id: %5
  %6 = tuple ()                                   // user: %7
  return %6 : $()                                 // id: %7
}

When writeback is needed, we still emit the two retains (balanced with the
get and set calls).




Swift SVN r11854
2014-01-03 06:34:27 +00:00
Chris Lattner
10ab56c140 mechanical transition of lvalue emission logic from trafficing in SILValue's
to trafficing in ManagedValues.  No functionality change (yet), we just needed
more management in the mix.


Swift SVN r11851
2014-01-03 05:40:30 +00:00
Chris Lattner
45b78bdf50 rework SILGenFunction::prepareAccessorBaseArg to work with any base type:
it either passes the base as inout or as a +1 rvalue (e.g. references),
metatype bases as a degenerate case.



Swift SVN r11840
2014-01-03 00:58:21 +00:00
Chris Lattner
8f06ca3f2f remove the dead 'resultType' argument from emitGetAccessor.
Swift SVN r11806
2014-01-02 00:51:15 +00:00
Chris Lattner
7e8a382ac2 Rework @inout handling in SILGen. Now @inout is emitted as an rvalue,
not as part of the lvalue path.  This means that the arguments to a 
function (for example) are always rvalues - @inout arguments are not a
special case all over the place.

This removes emitLValueOrRValueAsRValue and emitLValueAsRValue, because
the lvalue that both of them were trying to handle was @inout, not @lvalue.



Swift SVN r11805
2014-01-02 00:49:10 +00:00
Chris Lattner
c73bfe2530 rework sema and silgen of SuperRefExpr. The most notable change is that it
is no longer an lvalue, since it doesn't make sense to assign to super.

This eliminates a bunch of special cases and simplifies things.



Swift SVN r11803
2014-01-01 22:51:10 +00:00