Commit Graph

768 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
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
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
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
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
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
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
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
Joe Groff
706e7baac4 SILGen: Handle abstraction differences in stored property access.
When we produce a physical LValue with an abstraction difference, cap off the LValue with a logical "OrigToSubstComponent", which enacts the abstraction change on load or store, and introduces a writeback for the property when used in an @inout context.

Swift SVN r11498
2013-12-20 02:25:11 +00:00
Chris Lattner
b29748a6be remove the ASTContext argument from Type::transform,
(various) FunctionType::get's, ArrayType::get,
ArraySliceType::get, OptionalType::get, and a few
other places.

There is more to be done here, but this is all I plan to do
for now.


Swift SVN r11497
2013-12-20 02:23:21 +00:00
Joe Groff
017440165e Fix the weird capitalization of MetaTypeType.
Swift SVN r11475
2013-12-19 18:43:08 +00:00
Chris Lattner
1788421e5d Change SILGen to lower and bind non-address-only 'let' variables
as values, without a box at all.  This generalizes some of the
previous hacks I had for silgen'ing 'self' as a value instead of
a box, and capturing them with CaptureKind::Constant.




Swift SVN r11360
2013-12-16 20:36:16 +00:00
Chris Lattner
3c03c0b5e4 rework emitOptionalToRef to use an optional code sequence to get a null class
reference, eliminating the last thing that creates a SIL builtin zero.


Swift SVN r11051
2013-12-09 23:37:51 +00:00
Joe Groff
e37897b57b SILGen: Always emit physical access to stored properties in 'init' and 'destructor', even for @objc stored properties.
This gives more predictable semantics for initializers and destructors under the DI model, and also unblocks enabling the DI model at all for @objc initializers. <rdar://problem/15614052>

Swift SVN r11029
2013-12-09 17:31:04 +00:00
John McCall
4bba9b38f8 Make several new interfaces traffic in AbstractionPatterns.
Swift SVN r10621
2013-11-21 02:19:46 +00:00
Doug Gregor
84cf9d1183 Cope with local functions within a generic context that have no captures.
Previously, we were just ignoring the generic parameters. Should
finish off <rdar://problem/15463549>.


Swift SVN r10570
2013-11-20 00:01:19 +00:00
Joe Groff
84ab2a47dc SILGen: Peephole physical lvalue-to-lvalue assignments.
When assigning between physical lvalues, emit a 'copy_addr' instead of a load + assign sequence. This provides a higher-level semantic instruction to SIL passes, and also produces better code in many cases.

It unfortunately exposes another bug in DI which affects the test/IRGen/objc.swift test, which I've XFAILed until it can be fixed.

Swift SVN r10564
2013-11-19 23:17:55 +00:00
John McCall
20e58dcf93 Change the type of function values in SIL to SILFunctionType.
Perform major abstraction remappings in SILGen.  Introduce
thunking functions as necessary to map between abstraction
patterns.

Swift SVN r10562
2013-11-19 22:55:09 +00:00
Adrian Prantl
07bdac2c12 silence warning
Swift SVN r10505
2013-11-15 23:24:47 +00:00
Joe Groff
e75ca8bef3 AST: Improve modeling of static property references.
Instead of cutting corners by emitting a static property reference as a DeclRef, do the right thing and build a MemberRef on the metatype. Add the smarts to SILGen to recognize static property MemberRefs and emit global_addr instructions for (nongeneric, nondynamic) static properties.

Swift SVN r10482
2013-11-15 01:00:44 +00:00
John McCall
08171453da Make it a bit easier to propogate expressions around instead
of having to lower to an RValue.

This is valuable because we can often emit an expression to a
desired abstraction level more efficiently than just emitting
it to minimal abstraction and then generalizing.

Swift SVN r10455
2013-11-14 05:25:06 +00:00
Chris Lattner
4968cc208b A couple of related changes:
- Enhance SILBuilder::emitStrongRelease to be smarter.
- Start using emitStrongRelease in type lowering, SILGen,
  CapturePromotion (replacing its implementation of the
  same logic), and MandatoryInlining (one more place)
- Rename the primitive createStrongRetain/ReleaseInst
  instructions to lose their suffix.
- Now that createStrongRetain/ReleaseInst are not special
  cases from the naming perspective, remove some special cases
  from DeserializeSIL and ParseSIL.
  


Swift SVN r10449
2013-11-14 02:21:27 +00:00
Chris Lattner
9570e1fb0c Remove the "createStrongRetain" and "createStrongRelease" SILBuilder methods.
They are the same as createStrongRetainInst and createStrongReleaseInst, but
peephole away FunctionRefInst.  It turns out that there is only a couple
places in SILGen where this behavior is necessary, and this tramples on the
general pattern used in SILBuilder.


Swift SVN r10448
2013-11-14 02:00:41 +00:00
Chris Lattner
f959378aa3 revert my previous patch. It doesn't break anything, but there is more going on
here than I think I understand, so I'm backing off.


Swift SVN r9909
2013-11-03 18:46:10 +00:00
Chris Lattner
aa4d91972c remove some peephole logic that is trying to turn a copyaddr into its component
parts.  Our canonical representation is going towards more complex operations
now, so this isn't useful.


Swift SVN r9908
2013-11-03 18:41:12 +00:00
Jordan Rose
64e0b2200a Make sure to resolve library intrinsics before using them.
Otherwise, compiling the standard library will try to use, say,
_getOptionalValue() before that function has any type.

Swift SVN r9671
2013-10-25 17:30:41 +00:00
Dmitri Hrybenko
80d753d0ab Portability: use std::make_tuple instead of relying on a libc++ extension (an
implicit constructor in std::tuple)


Swift SVN r9615
2013-10-23 06:17:28 +00:00
Dmitri Hrybenko
acdd5b120a Make type checker debug output redirectable
Introduce a replaceable TypeCheckerDebugConsumer for this.


Swift SVN r9555
2013-10-21 20:26:32 +00:00
Joe Groff
ad379929fd SILGen: Don't apply the copy_addr peephole to initializations from computed lvalues.
Materializing the result of the getter isn't worth it, I don't think.

Swift SVN r9351
2013-10-15 17:20:48 +00:00
Joe Groff
d9560a9bd6 SILGen: Simplify lvalue initialization peephole when dealing with semantic stores.
Instead of trying to anticipate every combination of source and destination [unowned]/[weak] qualifiers, just back off on the copy_addr peephole and let the old path handle these cases as before.

Swift SVN r9030
2013-10-08 21:14:44 +00:00
Joe Groff
2ffd735255 SILGen: Peephole lvalue-to-lvalue initializations as copy_addrs.
If we're using emitExprInto to emit a LoadExpr, we can handle that by emitting a copy_addr from the underlying lvalue to the initialization instead of building and storing the rvalue, which plays better with the direction we're taking for value semantics optimizations.

This is currently guarded behind a flag -enable-silgen-lvalue-peepholes because it introduces a miscompile in the stdlib that crashes some tests; requires further investigation before making live.

Swift SVN r9027
2013-10-08 20:44:09 +00:00
Joe Groff
7fc2720826 SILGen: Replace uses of TypeLowering::emitCopyInto with CopyAddrInsts.
Chris and I want to move toward canonicalizing on more abstract aggregate operations (copy_addr) instead of on the component load/store/copy|destroy_value/retain|release operations, which is easier for early passes like inout deshadowing, NRVO, and move optimization to reason about. As a first step, replace the handful of places where SILGen currently used TypeLowering::emitCopyInto with simple CopyAddrInst insertions. This affects inout initializations and emitSemanticLoadInto, neither of which should disturb early passes that relied on the old behavior.

Swift SVN r8991
2013-10-07 21:17:48 +00:00
Doug Gregor
611a5cce4b Replace the library-defined postfix '!' with an expr-postfix production.
As with the monadic '?', we treat any left-bound '!' as a postfix
operator. Currently, it extracts the value of its optional
subexpression, failing at run-time if the optional is empty.


Swift SVN r8948
2013-10-06 23:09:58 +00:00
John McCall
97033996ba Rework optional intrinsic methods to work with RValues.
Swift SVN r8836
2013-10-02 05:48:29 +00:00
John McCall
298577676e Introduce the monadic ? operator.
A ? operator is interpreted as this if it's left-bound,
so ternary operators now have to be spaced on the left.

Swift SVN r8832
2013-10-02 01:27:45 +00:00
Joe Groff
ce2e87fa3e SILGen: Emit 'x as? T' conditional casts.
Wrap the result of a checked_cast_br into an Optional using John's injection functions.

Swift SVN r8811
2013-10-01 21:11:34 +00:00
Joe Groff
82a18333ed SIL: Purge SpecializeInst.
Make ApplyInst and PartialApplyInst directly take substitutions for generic functions instead of trying to stage out substitutions separately. The legacy reasons for doing this are gone.

Swift SVN r8747
2013-09-28 00:15:45 +00:00
Doug Gregor
0d33ff3f40 Teach SILGen to directly emit optional injection operations for dynamic lookup.
... rather than synthesizing expressions in the AST.


Swift SVN r8723
2013-09-27 14:12:33 +00:00
Jordan Rose
626479fbd9 s/property/accessor/ in SILGen and TypeLowering
Several places in SILGen and TypeLowering were using "property" to mean
"accessor" (for both variables and subscripts).

Swift SVN r8702
2013-09-26 21:53:03 +00:00
Jordan Rose
e05c03d5bc Standardize terminology for "computed", "stored", "variable", and "property".
These are the terms sent out in the proposal last week and described in
StoredAndComputedVariables.rst.

variable
  anything declared with 'var'
member variable
  a variable inside a nominal type (may be an instance variable or not)
property
  another term for "member variable"
computed variable
  a variable with a custom getter or setter
stored variable
  a variable with backing storage; any non-computed variable

These terms pre-exist in SIL and IRGen, so I only attempted to solidify
their definitions. Other than the use of "field" for "tuple element",
none of these should be exposed to users.

field
  a tuple element, or
  the underlying storage for a stored variable in a struct or class
physical
  describes an entity whose value can be accessed directly
logical
  describes an entity whose value must be accessed through some accessor

Swift SVN r8698
2013-09-26 18:50:44 +00:00
Doug Gregor
3a72c7ff88 Use dynamic dispatch for [objc] properties and methods used in lvalues.
There are two major restrictions on this at the moment:
  1) It only applies to [objc] properties/subscripts (where we go
  through Objective-C dispatch). It still does static dispatch for
  non-[objc] properties/subscripts in classes.
  2) The Clang importer doesn't mark imported Objective-C properties
  and subscript operators as [objc], so this is useless in practice.



Swift SVN r8691
2013-09-26 14:13:19 +00:00