Commit Graph

6749 Commits

Author SHA1 Message Date
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
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
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
e57f8e436d simplify tuple processing code. We only want to do tuple element operations
in memory of the available type is address only, so simplify a check and
remove the predicate (which happens to be out of date anyway).


Swift SVN r12814
2014-01-22 23:36: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
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
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
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
90e1b572f0 split the ManagedValue class out to its own .h/.cpp files.
Swift SVN r12702
2014-01-22 05:42:34 +00:00
Doug Gregor
d52cec4b20 Eliminate a pile of literal identifiers for self, init, destructor, etc.
... because I can't stomach adding another one of these.


Swift SVN r12687
2014-01-22 01:09:49 +00:00
Joe Groff
81759cde52 SILGen: Strip non-semantic pattern nodes before dispatching.
Don't crash when sugary pattern nodes like Paren and Var get mixed and we try to cast subpatterns to the expected semantic pattern type.

Swift SVN r12674
2014-01-21 23:56:11 +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
8563ebc36e rework and tidy SILGenLValue::visitMemberRefExpr to make the logic
flow better: the getter/setter case is the simple case, so switch
it to be the early out.


Swift SVN r12579
2014-01-20 16:10:22 +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
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
Chris Lattner
a0f0c28868 Two related but (theoretically at least) seperable changes:
1. Implement parser and sema support for our subscript syntax proposal in
   protocols.  Now you have to use subscript(..) { get } or  {get set} to 
   indicate what you want.  I suspect that the syntax will evolve, but at
   least we can express what we need now.
2. Change the representation of SubscriptDecls in protocols to make 
   (empty) funcdecls for the getter and setter.  This guarantees that 
   every subscript has at least a getter.



Swift SVN r12555
2014-01-19 01:35:13 +00:00
Chris Lattner
0292a5f34e merge objc thunk generation for subscripts into the thunk
generation logic for vardecls.  They are the same, subscripts
are always just computed.


Swift SVN r12542
2014-01-18 20:28:49 +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
a8d8e14254 introduce AbstractStorageDecl. Right now, just
move OverriddenDecl and usesObjCGetterAndSetter() up to it.
This allows usesObjCGetterAndSetter to subsume the logic
for subscript decls as well.



Swift SVN r12535
2014-01-18 19:08:39 +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
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
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