Commit Graph

6754 Commits

Author SHA1 Message Date
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
103e5e7664 remove some unneeded global namespace qualifiers.
Swift SVN r11849
2014-01-03 04:26:53 +00:00
Chris Lattner
ef5ee1c169 Remove AddressComponent, merging its functionality into ValueComponent
Swift SVN r11847
2014-01-03 02:05:15 +00:00
Chris Lattner
1b53a1bbd2 remove the concept of “settable” from SILGenLValue - all lvalues are now settable. Things that aren’t settable are rvalues now.
Swift SVN r11843
2014-01-03 01:20:15 +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
ce77d4aac5 RefComponent and MetatypeComponent are both doing pretty much the same thing in LValueEmitter. Merge them in preparation for them getting further generalized.
Swift SVN r11835
2014-01-02 23:03:02 +00:00
Chris Lattner
cdb6541c20 move handling of addressofexpr back into SILGenLValue::visitAddressOfExpr,
it is simpler there than in visitRec.


Swift SVN r11815
2014-01-02 17:57:00 +00:00
Chris Lattner
917d2a1d9c remove the dead 'TypeConverter::getMethodSelfType' method, which
is also incorrect.


Swift SVN r11807
2014-01-02 00:59:01 +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
bcc46aef5d now that super is playing nicely with the type system, all the old code
I originally wrote to turn "loadexpr(declrefexpr(letdecl))" is dead, remove
it.  Let decls are now always rvalues, so they never are loaded.


Swift SVN r11804
2014-01-01 22:58:09 +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
Chris Lattner
be58684653 further detangle @inout and @lvalue types, making the code more specific
and simpler.


Swift SVN r11801
2014-01-01 21:35:31 +00:00
Chris Lattner
859883d88e further detangle @lvalue and @inout. types, this time in libsil.
Swift SVN r11800
2014-01-01 20:46:54 +00:00
Chris Lattner
d2a33362dc Fix getRValueType() to not strip off @inout types, only @lvalue types.
- Introduce a new TypeBase::getInOutObjectType() that strips off @inout types
- Switch stuff that is calling getRValueType() to call getInOutObjectType()
  when they are stripping @inout, not @lvalue (this is primarily around
  stuff working with self)
- Update testcases, some diagnostics improve around & handling.

This fixes rdar://15708430 and rdar://15729093.



Swift SVN r11794
2014-01-01 18:56:44 +00:00
Chris Lattner
6d25464103 simplify some code that is reimplementing emitManagedRetain to just
call emitManagedRetain.


Swift SVN r11770
2013-12-31 06:31:55 +00:00
Chris Lattner
9a74e8af78 Add some PrettyStackTrace entries to identify the top level generator of a
silfunction when we get a crash.

Merge AutoClosure and ExplicitClosure generation logic.

NFC.


Swift SVN r11769
2013-12-31 05:35:51 +00:00
Chris Lattner
468ead25a6 allow 'var' and 'let' to appear in patterns (not just matching patterns).
This allows them to appear in argument lists of functions, enabling behavior
like this:

func test_arguments(a : Int, var b : Int, let c : Int) {
  a = 1  // ok (for now).
  b = 2  // ok.
  c = 3  // expected-error {{cannot assign to the result of this expression}}
}



Swift SVN r11746
2013-12-30 21:48:06 +00:00
Chris Lattner
fafab67216 fix a crash in SILGen when calling through a 'let' vardecl, which was
because let vardecls can't be turned into SILDeclRef constant references.


Swift SVN r11734
2013-12-30 07:17:57 +00:00
Chris Lattner
2aab668817 Change two places that can only see @inout types, not @lvalue types.
Swift SVN r11733
2013-12-30 06:57:13 +00:00
Chris Lattner
9ae289de46 Drive the semantic wedge harder into lvalues. Now, instead of having one LValueType
with qualifiers on it, we have two distinct types:
 - LValueType(T) aka @lvalue T, which is used for mutable values on the LHS of an
   assignment in the typechecker.
 - InOutType(T) aka @inout T, which is used for @inout arguments, and the implicit
   @inout self argument of mutable methods on value types.  This type is also used
   at the SIL level for address types.

While I detangled a number of cases that were checking for LValueType (without checking
qualifiers) and only meant @inout or @lvalue, there is more to be done here.  Notably,
getRValueType() still strips @inout, which is totally and unbearably wrong.



Swift SVN r11727
2013-12-29 22:23:11 +00:00
Chris Lattner
eb576ba2cd Now that lvalue types are more squared away, RequalifyExpr is completely
dead.  Remove it.


Swift SVN r11710
2013-12-29 05:06:54 +00:00
Chris Lattner
d3c91387e9 Substantially simplify the API to LValueType now that nonsettable is gone.
Swift SVN r11703
2013-12-28 22:48:44 +00:00
Joe Groff
d3c0532205 SILGen: Reabstract enum payloads matched out by a 'switch' pattern.
Swift SVN r11696
2013-12-28 16:42:06 +00:00
Chris Lattner
b1a882c093 Fix a problem where let decls of tuple type would die in SILGen when
being closed over.  If we allowed arguments to have tuple type
in the SILFunctionType type system, this would just work.  As it is,
we have to do a bit of [re|de]structuring on the partial_apply and
the closure body side to work things out.


Swift SVN r11680
2013-12-27 23:22:57 +00:00
Chris Lattner
5faf530cf2 implement restructuring assignment of let decls, repurposing the existing
implosion logic.  This resolves rdar://15716277


Swift SVN r11679
2013-12-27 22:30:28 +00:00
Chris Lattner
dc71faa766 Add a local cleanup to fix a problem in foreach expansion when the 'next()' call
would produce temporary stack allocations.  Before the dealloc_stack would get 
generated at the end of the foreach sequence, a violation the stack nesting verifier
caught.


Swift SVN r11673
2013-12-27 20:21:37 +00:00
Chris Lattner
4f4c698ed6 Change 'self' to be an rvalue instead of an lvalue in non-@mutating
struct methods.  This does not including properties and subscripts,
but covers the bulk of the change.  The implication of this is that
the compiler now rejects mutations of self in a non-@mutating method,
and rejects attempts to call a @mutating method from a non-@mutating
method.

Along with this:
 - Fix a refcounting bug in SILGenExpr where I emitted multiple releases
   in the rvalue member_ref_expr case, which was exposed by the 
   testsuite now that rvalues are being used a lot more.
 - Change a few native binding things in objc/Foundation to understand
   that String is passed by value now when calling size() and that
   you can't take the address of self in a non-mutating method (this
   should probably pass the components by value instead of passing
   &self, for better performance).  I filed rdar://15726720 to track
   this.
 - Update a ton of testcases.  We now don't materialize nearly as much
   as we used to.
 - Brutalize the test/stdlib/Getopt.swift testcase to work, now that
   the "GetoptLongOptions().noArgument("foo")" builder pattern doesn't
   work anymore (noArgument is a @mutating method, which isn't allowed
   on an rvalue temporary).



Swift SVN r11662
2013-12-26 17:38:03 +00:00
Joe Groff
3e30cbcfef SILGen/IRGen: Don't emit top_level_code for libraries.
If there's no script-mode file in a module, don't produce a top_level_code SILFunction for it, and don't consider emitting an LLVM global_ctor for it. We should never emit static constructors from user code anymore.

Swift SVN r11644
2013-12-26 00:18:29 +00:00
Chris Lattner
1964cf94e2 When the base of a computed property is an rvalue, the result should
be an rvalue as well.  This is NFC other than changing one terrible
diagnostic into a different one.


Swift SVN r11637
2013-12-25 22:10:31 +00:00
Chris Lattner
a792065c57 continue rvalue world domination. Switch get-only subscript expressions to produce
rvalues instead of non-modifiable lvalues.


Swift SVN r11634
2013-12-25 21:34:52 +00:00
Chris Lattner
84ea29a9f6 Rename GetterSetterComponent::subscriptExpr to subscriptIndexExpr,
since it is the expression for the index, not the *entire* 
SubscriptExpr itself.  NFC.



Swift SVN r11633
2013-12-25 20:30:16 +00:00
Chris Lattner
f99492202f Make some fairly major internal changes to our value system: now, get-only
properties are represented as rvalues, not non-mutable lvalues.  As part of
this, isReferencedAsLValue() only returns true for mutable VarDecls.

This required some pretty serious rearrangement and refactoring of code,
because now (among other things) get-only properties can be emitted as rvalues,
so the rvalue machinery needs to be able to produce getter calls.

This is an important step towards getting proper value semantics going (for
'let's etc) and also allows us to materialize addresses less often.  As a
simple example, before we would silgen this:

struct S {
  var i : Int
}
var P : S { get: ... }
func f() {
  print(P.i)
}

into:

 %2 = function_ref @_TF1tg1PVS_1S : $@thin () -> S // user: %3
  %3 = apply %2() : $@thin () -> S                // user: %5
  %4 = alloc_stack $S                             // users: %9, %6, %5
  store %3 to %4#1 : $*S                          // id: %5
  %6 = struct_element_addr %4#1 : $*S, #i         // user: %7
  %7 = load %6 : $*Int64                          // user: %8

now we generate:

  %2 = function_ref @_TF1tg1PVS_1S : $@thin () -> S // user: %3
  %3 = apply %2() : $@thin () -> S                // user: %4
  %4 = struct_extract %3 : $S, #i                 // user: %5



Swift SVN r11632
2013-12-25 17:43:10 +00:00
Joe Groff
e06ee37dca Enable SIL protocol witnesses.
We should be able to cut out another layer of IRGen grime now.

This does XFAIL one test, test/Prototypes/TextFormatting.swift, which fails because of a weird archetype ordering in a nested substitution list. This should get sorted out by switching to interface types, so I'm going to let it go until then.

Swift SVN r11618
2013-12-24 04:36:03 +00:00
Joe Groff
ba7c1ab281 SILGen: Substitution conformances don't actually always match protocol declaration order for associated types.
What's a little more linear search? Maybe there's some other predictable order.

Swift SVN r11616
2013-12-24 04:35:56 +00:00
Chris Lattner
542d7dd63e Fix a problem when loading an address-only rvalue element from an address-only rvalue
container.  Previously we destroyed just the accessed element, not the entire container.
Thanks to Joe for the consult on the best (and simpler!) way to fix this.


Swift SVN r11615
2013-12-24 02:06:18 +00:00
Chris Lattner
c17e860ef2 when producing a +1 value, make sure to manage it so that it gets balanced.
NFC since this isn't an active codepath (yet)


Swift SVN r11606
2013-12-23 17:25:27 +00:00
Chris Lattner
451da95f1a Fix destruction of address-only let decls, which do have boxes despite
being immutable.  This addresses rdar://15717123.


Swift SVN r11604
2013-12-23 06:58:05 +00:00
Chris Lattner
3c83c17967 fix MemberRefExpr on an address-only base that produces a non-address-only value.
Swift SVN r11601
2013-12-23 06:41:06 +00:00
Chris Lattner
b92c57fd3e Extend MemberRefExpr in a fairly substantial way: now it is ok, when applied to a
struct rvalue, to produce a struct element directly, without converting the rvalue
to an lvalue.

This means that it no longer materializes an lvalue when applied to a let declaration
or other rvalue.  For example, this testcase:

struct X { var a,b : Int} 
func g() -> X { return X(1,2) }

func f() {
  let a = g().a
}

used to sema into:

       (load_expr implicit type='Int'
          (member_ref_expr type='@inout (implicit, nonsettable)Int' decl=t.(file).X.a@t.swift:2:16
            (materialize_expr implicit type='@inout (implicit)X'
              (call_expr type='X'

and silgen into:

  %1 = function_ref @_TF1t1gFT_VS_1X : $@thin () -> X // user: %2
  %2 = apply %1() : $@thin () -> X                // user: %4
  %3 = alloc_stack $X                             // users: %7, %5, %4
  store %2 to %3#1 : $*X                          // id: %4
  %5 = struct_element_addr %3#1 : $*X, #a         // user: %6
  %6 = load %5 : $*Int64

It now sema's into:
        (member_ref_expr type='Int' decl=t.(file).X.a@t.swift:1:16
          (call_expr type='X'

and silgens into:

  %1 = function_ref @_TF1t1gFT_VS_1X : $@thin () -> X // user: %2
  %2 = apply %1() : $@thin () -> X                // user: %3
  %3 = struct_extract %2 : $X, #a

I think I'm finally starting to grok Doug's crazy typechecker magic.



Swift SVN r11599
2013-12-23 06:24:55 +00:00
Joe Groff
ee71669a52 IRGen: Handle @objc protocols in the -emit-sil-protocol-witness-tables regime.
These still can't ever take any extra polymorphic params without breaking the calling convention, so protocol_method still needs to produce a thin value in SIL, and we have to ensure we don't add any extra polymorphic params in the IR signature.

Swift SVN r11594
2013-12-23 03:57:38 +00:00
Joe Groff
312096587e SILGen: Assign protocol witnesses a debug scope.
Swift SVN r11589
2013-12-23 02:45:23 +00:00
Joe Groff
f6205d25c3 SILGen: Fix the protocol witness label mismatch problem a third way.
r11586 is still too weak to handle both a label and an abstraction change. Instead of trying to handle this case in the guts of the reabstraction machine, where it ends up breaking other things, pre-sanitize the witness and requirement types before feeding them in. This is gross, but the keyword overhaul will hopefully make this unnecessarily before long.

Swift SVN r11588
2013-12-23 02:16:43 +00:00
Joe Groff
9888b43d33 Fix r11580 in a more targeted fashion.
Gratuitously stripping the labels interferes with (T : U -> V) abstraction changes. Only strip the labels where strictly necessary for correct behavior for now.

Swift SVN r11586
2013-12-23 00:59:29 +00:00
Joe Groff
8bd65469cf SILGen: Ignore property requirements when emitting witness tables.
Apparently these exist in the stdlib, and the old IRGen witness table builder ignores them. Let's follow suit for now.

Swift SVN r11585
2013-12-23 00:59:27 +00:00
Joe Groff
d241f19719 SILGen: Handle abstraction differences involving single-element labeled tuples.
In a case like:

protocol LabeledRequirement {
  func method(x: Loadable)
}

struct UnlabeledWitness : LabeledRequirement {
  func method(_: Loadable) {}
}

The original requirement type is represented as a labeled single-element TupleType, and the witness is represented as a scalar, but we want to disregard the label and consider the scalars in parallel. Do a pre-pass to strip single-element labels first before trying to destructure or indirect tuples.

Swift SVN r11580
2013-12-23 00:03:50 +00:00
Joe Groff
65f45d69ab SILGen: Only apply the primary archetype substitutions to an archetype_method.
This matches what SIL expects for generic function applications. Add a 'getPrimarySubstitutions' convenience method to ConcreteDeclRef.

Swift SVN r11579
2013-12-22 23:20:35 +00:00
Chris Lattner
f7247fbed3 Fix SILGenFunction::emitReferenceToDecl to property return references to
'let' declarations +1.  This isn't used yet, as the peephole around LoadExprs
is still doing all the work here (and it is already +1 correct).


Swift SVN r11573
2013-12-22 21:55:40 +00:00
Chris Lattner
bc2fa50271 Start driving a stronger wedge between lvalue and rvalues, by making RValueEmitter
only handle rvalues.  Clients that can either have an lvalue or an rvalue (which 
are few, and will be diminishing as other planned changes happen like the tuple
vs argument split) use a specific api to indicate such.


Swift SVN r11572
2013-12-22 20:34:25 +00:00