Commit Graph

1590 Commits

Author SHA1 Message Date
Joe Groff
9f698b67d8 Revert "SILGen: Use interface types in RValueEmitter's implementation."
This reverts commit r13053. It's dependent on 13036, which was reverted.

Swift SVN r13065
2014-01-28 22:05:34 +00:00
Joe Groff
357a242034 SILGen: Use interface types in RValueEmitter's implementation.
Cut over to using interface types and injecting context from the SILFunction as needed in all of the expression lowering code.

Swift SVN r13053
2014-01-28 05:25:57 +00:00
Chris Lattner
8735a76b0b Simplify emitRValueForPropertyLoad and make it work when we can have
rvalues that are both computed and have storage.


Swift SVN r13010
2014-01-27 22:10:34 +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
ddc5ca81d6 Fix <rdar://problem/15858869> *all* objc accessors disabled in init methods, not just for self
This patch: 
 - Changes sema to set the "IsDirectPropertyAccess" on MemberRefExprs
   in inits/destructors that should be done directly because they are
   on the local object.
 - Removes the "SGF.AlwaysDirectStoredPropertyAccess" bool in SILGen,
   which was the source of the problem above and was otherwise problematic.

This will get a bit simpler when -enable-new-objc-properties rolls out. 


Swift SVN r12967
2014-01-26 07:23:42 +00:00
Chris Lattner
91fb51100d Introduce a new kind of StorageDecl called StoredObjC. These are
properties that are (usually) accessed through getters and setters, but
which have storage.  Nothing generates these yet.


Swift SVN r12902
2014-01-24 05:15:11 +00:00
Chris Lattner
690e8a38af switch places the ignore the result of an rvalue to allow it to be +0. No
impact on stdlib or testsuite.


Swift SVN r12879
2014-01-23 22:06:21 +00:00
Chris Lattner
246c301bf5 enhance emission of tupleelementexprs to know about +0 values to
avoid temporaries.  This exposed a bug in the RValue tuple scalarization
logic handling +0 values.  This has no impact on the stdlib.


Swift SVN r12874
2014-01-23 20:17:32 +00:00
Chris Lattner
c6a334ab6e teach SILGenFunction::emitLoad that clients allowing +0 results don't
need the load (and temporary, and cleanup) to actually be emitted for
address-only operands.  They can just use the physical lvalue as the +0 base.

In this example:
struct GenericStruct<T> {
  var a : T
  var b : Int

  func getA() -> T {
    return a
  }

  func getB() -> Int {
    return b
  }
}

we used to produce:

sil @_TFV2t213GenericStruct4getAU__fGS0_Q__FT_Q_ : $@cc(method) @thin <$T_0_0> (@out $T_0_0, @in GenericStruct<$T_0_0>) -> () {
bb0(%0 : $*T, %1 : $*GenericStruct<T>):
  debug_value_addr %1 : $*GenericStruct<T>  // let self // id: %2
  %3 = alloc_stack $GenericStruct<T>              // users: %8, %7, %5, %4
  copy_addr %1 to [initialization] %3#1 : $*GenericStruct<T> // id: %4
  %5 = struct_element_addr %3#1 : $*GenericStruct<T>, #a // user: %6
  copy_addr %5 to [initialization] %0 : $*T       // id: %6
  destroy_addr %3#1 : $*GenericStruct<T>          // id: %7
  dealloc_stack %3#0 : $*@local_storage GenericStruct<T> // id: %8
  destroy_addr %1 : $*GenericStruct<T>            // id: %9
  %10 = tuple ()                                  // user: %11
  return %10 : $()                                // id: %11
}

sil @_TFV2t213GenericStruct4getBU__fGS0_Q__FT_Si : $@cc(method) @thin <$T_0_0> (@in GenericStruct<$T_0_0>) -> Int64 {
bb0(%0 : $*GenericStruct<T>):
  debug_value_addr %0 : $*GenericStruct<T>  // let self // id: %1
  %2 = alloc_stack $GenericStruct<T>              // users: %7, %6, %4, %3
  copy_addr %0 to [initialization] %2#1 : $*GenericStruct<T> // id: %3
  %4 = struct_element_addr %2#1 : $*GenericStruct<T>, #b // user: %5
  %5 = load %4 : $*Int64                          // user: %9
  destroy_addr %2#1 : $*GenericStruct<T>          // id: %6
  dealloc_stack %2#0 : $*@local_storage GenericStruct<T> // id: %7
  destroy_addr %0 : $*GenericStruct<T>            // id: %8
  return %5 : $Int64                              // id: %9
}

now we produce:

sil @_TFV2t213GenericStruct4getAU__fGS0_Q__FT_Q_ : $@cc(method) @thin <$T_0_0> (@out $T_0_0, @in GenericStruct<$T_0_0>) -> () {
bb0(%0 : $*T, %1 : $*GenericStruct<T>):
  debug_value_addr %1 : $*GenericStruct<T>  // let self // id: %2
  %3 = struct_element_addr %1 : $*GenericStruct<T>, #a // user: %4
  copy_addr %3 to [initialization] %0 : $*T       // id: %4
  destroy_addr %1 : $*GenericStruct<T>            // id: %5
  %6 = tuple ()                                   // user: %7
  return %6 : $()                                 // id: %7
}

sil @_TFV2t213GenericStruct4getBU__fGS0_Q__FT_Si : $@cc(method) @thin <$T_0_0> (@in GenericStruct<$T_0_0>) -> Int64 {
bb0(%0 : $*GenericStruct<T>):
  debug_value_addr %0 : $*GenericStruct<T>  // let self // id: %1
  %2 = struct_element_addr %0 : $*GenericStruct<T>, #b // user: %3
  %3 = load %2 : $*Int64                          // user: %5
  destroy_addr %0 : $*GenericStruct<T>            // id: %4
  return %3 : $Int64                              // id: %5
}

This cuts about 120 lines out of the stdlib (so, about 40 temporaries).


Swift SVN r12871
2014-01-23 19:44:43 +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
fc16e213fe Remove DestroyAddr/CleanupRValue/CleanupMaterializedValue.
All of the clients can use enterDestroyCleanup.


Swift SVN r12830
2014-01-23 00:49:36 +00:00
Chris Lattner
2cf6d814c7 more tidying:
- Strength reduce the interface to LogicalPathComponent::getMaterialized
   to now just return a SILValue for the address.  The full "Materialize"
   structure hasn't been needed since MaterializeExpr got removed.
 - Move 'struct Materialize' out of SILGen.h into SILGenLValues.cpp now
   that it is only used for logical property materialization.
 - Drop the dead 'loc' argument on DeallocStackCleanup.  The location is
   already specified when the cleanup is emitted.


Swift SVN r12827
2014-01-23 00:43:20 +00:00
Chris Lattner
5a557539cd fix a missing SGFContext passdown which would cause an extra copy for
address-only collections (if we ever had such a thing).


Swift SVN r12824
2014-01-23 00:23:29 +00:00
Chris Lattner
6e609bc886 tidy up various code formatting things and adopt
emitRValueAsSingleValue in more places to simplify code. NFC.



Swift SVN r12822
2014-01-23 00:15:49 +00:00
Doug Gregor
f4e6c85f62 Make sure to specialize a non-capturing closure in a generic context.
Fixes the rest of <rdar://problem/15883734>.


Swift SVN r12812
2014-01-22 23:15: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
b782bd4c56 'ignored' SGFContext's are also dead, remove them too.
Swift SVN r12799
2014-01-22 22:27:48 +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
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
Sean Callanan
3bc24605fd Updated the signature for emitReferenceToDecl to
take only the arguments LLDB uses, and also to
have a more accurate name.

<rdar://problem/15878172>


Swift SVN r12760
2014-01-22 19:03:52 +00:00
Chris Lattner
8fed381d46 the 'self' argument of SuperRefExpr and RebindSelfInConstructorExpr are always VarDecls,
use it instead of ValueDecl since it is more specific.


Swift SVN r12754
2014-01-22 18:25:19 +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
b13719be22 reapply r12727 (passing an SGFContext down to emitGetAccessor from
emitRValueForDecl when we have it), now with a testcase.  We formerly 
compiled this:

protocol P {}
var lp : P { get: }

func f() -> P {
  return lp
}

into:

sil @_TF3let1fFT_PS_1P_ : $@thin (@out P) -> () {
bb0(%0 : $*P):
  // function_ref let.lp.getter : let.P
  %1 = function_ref @_TF3letg2lpPS_1P_ : $@thin (@out P) -> () // user: %3
  %2 = alloc_stack $P                             // users: %5, %4, %3
  %3 = apply %1(%2#1) : $@thin (@out P) -> ()
  copy_addr [take] %2#1 to [initialization] %0 : $*P // id: %4
  dealloc_stack %2#0 : $*@local_storage P         // id: %5
  %6 = tuple ()                                   // user: %7
  return %6 : $()                                 // id: %7
}


we now avoid the copy:

sil @_TF3let1fFT_PS_1P_ : $@thin (@out P) -> () {
bb0(%0 : $*P):
  // function_ref let.lp.getter : let.P
  %1 = function_ref @_TF3letg2lpPS_1P_ : $@thin (@out P) -> () // user: %2
  %2 = apply %1(%0) : $@thin (@out P) -> ()
  %3 = tuple ()                                   // user: %4
  return %3 : $()                                 // id: %4
}



Swift SVN r12748
2014-01-22 17:51:38 +00:00
Chris Lattner
ba6bc88399 revert r12727, I didn't include a testcase.
Swift SVN r12746
2014-01-22 17:46:37 +00:00
Chris Lattner
57b4e9a383 pass down an SGFContext in a simple case where a getter is evaluated as an rvalue.
Swift SVN r12727
2014-01-22 07:30:16 +00:00
Chris Lattner
c521cda9ff inline emitReferenceToDecl into its only caller: emitRValueForDecl. Clients
now always know whether they are looking for an rvalue or lvalue.


Swift SVN r12726
2014-01-22 07:22:05 +00:00
Chris Lattner
c49e73c23d simplify emitReferenceToDecl: its only caller always passes in an
(explicit) uncurry level of zero.


Swift SVN r12723
2014-01-22 07:15:49 +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
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
af7821e23a Implement a narrow but effective hack to dramatically reduce retains and
releases produced by SILGen for non-@mutating struct methods.  Before,
we would retain the entire struct (which, if it contained class pointers
would emit an actual retain operations) even when accessing only some
part of it.  Handle a special case where we just retain the accessed
field.  For example, this testcase:

class C {}

struct SomeStruct {
  var c : C
  var i = 42


  func foo() -> Int {
    return i
  }
}

used to compile into:

sil @_TFV2t210SomeStruct3foofS0_FT_Si : $@cc(method) @thin (@owned SomeStruct) -> Int64 {
bb0(%0 : $SomeStruct):
  debug_value %0 : $SomeStruct  
  // this retains "c"
  %2 = copy_value %0 : $SomeStruct  
  %3 = struct_extract %2 : $SomeStruct, #i
  // this releases "c"
  destroy_value %2 : $SomeStruct
  // free the +1 argument.
  destroy_value %0 : $SomeStruct
  return %3 : $Int64
}

now it produces:

sil @_TFV2t210SomeStruct3foofS0_FT_Si : $@cc(method) @thin (@owned SomeStruct) -> Int64 {
bb0(%0 : $SomeStruct):
  debug_value %0 : $SomeStruct  // let self       // id: %1
  %2 = struct_extract %0 : $SomeStruct, #i        // user: %4
  destroy_value %0 : $SomeStruct                  // id: %3
  return %2 : $Int64                              // id: %4
}

As mentioned, this is a narrow hack intended to specifically benefit String, a more
general approach will come as I have time to implement it.



Swift SVN r12658
2014-01-21 21:34:14 +00:00
Chris Lattner
d4594b77a5 Switch the nominal type pattern matching destructuring logic to
use the new RValue emission infrastructure instead of duplicating
some of it.  This enables the use of computed properties, fixing
<rdar://problem/15859432> SILGen abort when pattern matching on computed property

and eliminates some code that future changes would otherwise have to 
worry about.  

There are other problems with this code (e.g. see rdar://15863069), so I think 
we should disable the feature until it has time to really bake, but this is still
useful progress in the right direction and is a net reduction of code.



Swift SVN r12618
2014-01-20 23:29:42 +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
5a502cf0a2 hoist emitDeclRefRValue out to SGF level so other clients can use it,
and rebrand it as emitRValueForDecl.  NFC.


Swift SVN r12597
2014-01-20 18:34:02 +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
6b93fc2034 simplify code now that getGetter/SetterType have been hoisted
to AbstractStorageDecl, NFC.


Swift SVN r12575
2014-01-20 15:37:20 +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
b4735381d0 Plumb the DeclContext of the use site down to the "doesVarDeclMemberProduceLValue"
function.  Pretty soon, whether something is an lvalue or not will depend on who is
asking.


Swift SVN r12507
2014-01-17 22:14:02 +00:00
Doug Gregor
4d6fc894be Propagate nil returned from a self.init or super.init call.
What we actually do here will likely change depending on how we want
to handle error propagation in general, but for now it suffices to
propagate the nil via an early exit.

Swift SVN r12440
2014-01-17 00:17:15 +00:00
Doug Gregor
133bb13848 Always assume that the result of calling self.init or super.init is of the appropriate subclass type.
Eliminates some Swift-side checking for a memory safety problem that
can only originate in Objective-C.

Swift SVN r12413
2014-01-16 19:58:09 +00:00
Doug Gregor
30a34e5a56 Lower the rebinding of 'self' in a super.init call to a cast when it can't fail.
Swift-rooted class hierarchies don't permit the replacement of "self",
so it's guaranteed that the 'self' returned from a 'super.init'
invocation is identical to the previous self. Elide the unconditional
checked downcast (that manifests as a call to
swift_dynamicCastClassUnconditional in the runtime) by putting in the
moral equivalent of a bitcast.

For Objective-C-rooted hierarchies, 'self' can be replaced, so memory
safety dictates that we use the unconditional checked downcast. Note
that this path is still unsafe against nil returns.

Swift SVN r12401
2014-01-16 06:01:22 +00:00
Doug Gregor
3a6db8292e Revert "Introduce the self_downcast SIL instruction to downcast the result of super.init."
We need to model the difference between Objective-C- and Swift-rooted
class hierarchies in SIL. IRGen is too late to handle nil returns.

This reverts commit 549db981ea0136a67aee3029aefe18a05d3c8833.

Swift SVN r12400
2014-01-16 06:01:21 +00:00
Doug Gregor
d19065048b Introduce the self_downcast SIL instruction to downcast the result of super.init.
No functional difference from the unconditional checked downcast we
had before, but this gives IRGen the chance to specialize the
implementation.

Swift SVN r12382
2014-01-16 04:24:56 +00:00
Doug Gregor
e5adce56ad Clarify SILGen lowering of the self-rebinding expression. NFC
Swift SVN r12377
2014-01-16 01:40:03 +00:00
Chris Lattner
1b6c2e321e change a few "createCopyValue"'s to "emitCopyValue" so that trivial types
don't get copyvalues.  This is mostly to make sure that only Typelowering and
silcloner are calling createCopyValue.


Swift SVN r12365
2014-01-16 00:27:32 +00:00
Chris Lattner
e180f9b601 Properly handle the case when a member_ref_expr on an rvalue struct
causes an abstraction change.


Swift SVN r12354
2014-01-15 22:19:03 +00:00
Chris Lattner
eacb823fd5 fix rdar://15821990 - Don't emit default value for type var in instance init() body.
Swift SVN r12319
2014-01-15 05:31:43 +00:00