Commit Graph

131 Commits

Author SHA1 Message Date
Michael Gottesman
543063ef0e [silgen] Make ManagedValue::forUnmanaged private and change users to use other more specific APIs.
I have been doing this over the past couple of days in preparation for changing
ManagedValue to specify the type of scope its cleanup is connected to.
2023-08-19 14:11:44 -07:00
Nate Chandler
c007bae723 [SIL] Added weak_copy_value.
The new instruction wraps a value in a `@sil_weak` box and produces an
owned value. It is only legal in opaque values mode and is transformed
by `AddressLowering` to `store_weak`.
2023-08-08 15:47:13 -07:00
Nate Chandler
e135c5cac7 [SIL] Added strong_copy_weak_value.
The new instruction unwraps an `@sil_weak` box and produces an owned
value. It is only legal in opaque values mode and is transformed by
`AddressLowering` to `load_weak`.
2023-08-08 15:47:13 -07:00
Nate Chandler
e5d87f75a8 [SIL] Add source formal type to checked_cast_br.
It is necessary for opaque values where for casts that will newly start
out as checked_cast_brs and be lowered to checked_cast_addr_brs, since
the latter has the source formal type, IRGen relies on being able to
access it, and there's no way in general to obtain the source formal
type from the source lowered type.
2023-07-27 15:04:15 -07:00
Erik Eckstein
b08710d911 SIL: add a bare attribute to alloc_ref
The `bare` attribute indicates that the object header is not used throughout the lifetime of the object.
This means, no reference counting operations are performed on the object and its metadata is not used.
The header of bare objects doesn't need to be initialized.
2023-06-29 06:57:05 +02:00
Evan Wilde
f3ff561c6f [NFC] add llvm namespace to Optional and None
This is phase-1 of switching from llvm::Optional to std::optional in the
next rebranch. llvm::Optional was removed from upstream LLVM, so we need
to migrate off rather soon. On Darwin, std::optional, and llvm::Optional
have the same layout, so we don't need to be as concerned about ABI
beyond the name mangling. `llvm::Optional` is only returned from one
function in
```
getStandardTypeSubst(StringRef TypeName,
                     bool allowConcurrencyManglings);
```
It's the return value, so it should not impact the mangling of the
function, and the layout is the same as `std::optional`, so it should be
mostly okay. This function doesn't appear to have users, and the ABI was
already broken 2 years ago for concurrency and no one seemed to notice
so this should be "okay".

I'm doing the migration incrementally so that folks working on main can
cherry-pick back to the release/5.9 branch. Once 5.9 is done and locked
away, then we can go through and finish the replacement. Since `None`
and `Optional` show up in contexts where they are not `llvm::None` and
`llvm::Optional`, I'm preparing the work now by going through and
removing the namespace unwrapping and making the `llvm` namespace
explicit. This should make it fairly mechanical to go through and
replace llvm::Optional with std::optional, and llvm::None with
std::nullopt. It's also a change that can be brought onto the
release/5.9 with minimal impact. This should be an NFC change.
2023-06-27 09:03:52 -07:00
John McCall
3332ce7d1e [NFC] Add a utility for this load take/borrow dance 2023-06-14 21:29:21 -04:00
Michael Gottesman
42b4b9a652 [move-only] Fix class setters of address only move only types.
We were not properly propagating along cleanups in SILGenProlog. I went through
SILGenProlog and fixed this.

rdar://109287977
2023-05-31 14:24:40 -07:00
Michael Gottesman
e6f1691122 [copy-operator] Add support for the copy operator in preparation for making consuming and borrowing no implicit copy.
Some notes:

1. I implemented this as a contextual keyword that can only apply directly to
lvalues. This ensures that we can still call functions called copy, define
variables named copy, etc. I added tests for both the c++ and swift-syntax based
parsers to validate this. So there shouldn't be any source breaks.

2. I did a little bit of type checker work to ensure that we do not treat
copy_expr's result as an lvalue. Otherwise, one could call mutating functions on
it or assign to it, which we do not want since the result of copy_value is

3. As expected, by creating a specific expr, I was able to have much greater
control of the SILGen codegen and thus eliminate extraneous copies and other
weirdness than if we used a function and had to go through SILGenApply.

rdar://101862423
2023-05-17 22:42:42 -07:00
Michael Gottesman
59fdfaddd1 [move-only] Spill noncopyable types that are objects using store_borrow if we call a resilient function that takes it in_guaranteed.
This ensures that given a class that contains a noncopyable type that contains
another noncopyable type:

```
@_moveOnly struct S2 {}
@_moveOnly struct S { var s2: S2 }
class C { var s: S }
```

if we call a resilient function that takes C.S.S2:

```
borrowVal(c.s.s2)
```

we properly spill s2 onto the stack using a store_borrow.

Why Do This?
------------

Currently SILGenLValue treats ref_element_addr as a base that it needs to load
from for both copyable and non-copyable types. We keep a separation of concerns
and require emission of resilient functions to handle these loaded values. For
copyable types this means copying the value and storing it into a temporary
stack allocation. For noncopyable types, we never actually implemented this so
we would hit an error in SILGenApply telling us that our resilient function
expected an address argument, but we are passing an object.

To work around this, I updated how we emit borrowed lvalue arguments to in this
case to spill the value into a temporary allocation using a store_borrow. I also
included a test that validates that we properly have a read exclusivity scope
around the original loaded from memory for the entire call site so even though
we are performing a load_borrow and then spilling it, we still have read
exclusivity to the original memory for the entire region meaning that we still
preserve the semantics.

rdar://109171001
2023-05-10 14:12:34 -07:00
Michael Gottesman
438974a2b9 [move-only] When emitting borrows for move only types, use a load [copy] instead of a load_borrow.
The reason why I am doing this is that otherwise if one has a function that
takes both a guaranteed and an owned parameter, we will break OSSA invariants
since the load [take] will invalidate the load_borrow. So instead, we put in a
load_borrow knowing that the move checker will convert it to a load_borrow
assuming that the two pass exclusivity checking.

NOTE: Because of some missing functionality in subsequent tests, I had to
disable one test (moveonly_escaping_definite_initialization.swift) and also add
some checks for copy of noncopyable object errors. They will go away in the next
2 commits.

rdar://108510987
2023-04-25 10:51:03 -07:00
Adrian Prantl
158772c2ab Rebase SILScope generation on top of ASTScope.
This patch replaces the stateful generation of SILScope information in
SILGenFunction with data derived from the ASTScope hierarchy, which should be
100% in sync with the scopes needed for local variables. The goal is to
eliminate the surprising effects that the stack of cleanup operations can have
on the current state of SILBuilder leading to a fully deterministic (in the
sense of: predictible by a human) association of SILDebugScopes with
SILInstructions. The patch also eliminates the need to many workarounds. There
are still some accomodations for several Sema transformation passes such as
ResultBuilders, which don't correctly update the source locations when moving
around nodes. If these were implemented as macros, this problem would disappear.

This necessary rewrite of the macro scope handling included in this patch also
adds proper support nested macro expansions.

This fixes

rdar://88274783

and either fixes or at least partially addresses the following:

rdar://89252827
rdar://105186946
rdar://105757810
rdar://105997826
rdar://105102288
2023-04-04 15:20:11 -07:00
nate-chandler
4ea51cfe33 Revert "Add a verify-di-hole assertion to SILBuilder." 2023-03-23 13:27:06 -07:00
Adrian Prantl
88b071bf9f Merge pull request #64494 from adrian-prantl/dihole-assertion
Add a verify-di-hole assertion to SILBuilder.
2023-03-22 12:50:17 -07:00
John McCall
3fe46464c7 Allow a SILFunctionArgument to be a parameter pack.
We might want to record the *sequence* of parameter decls associated
with a parameter pack, but currently we're not doing that.
2023-03-21 17:36:05 -04:00
Adrian Prantl
5129aea296 Add a verify-di-hole assertion to SILBuilder.
The verify-di-hole SILVerifier pass is very useful in catching incorrectly set
SILDebugScopes, but it can be very tedious to track down the root cause of a
verification failure. This patch replicates much of its functionality inside an
assertion in SILBuilder, which will result in a backtrace pointing directly to
where the offending scope is being set.
2023-03-21 09:40:11 -07:00
Michael Gottesman
0a2353f530 [silgen] Add a helper called SILGenBuilder::emitCopyAddrOperation.
This works by emitting an object level copy_addr if an address type is
loadable (that is using load [take] + store [init] instead of copy_addr).
2023-02-17 16:04:47 -08:00
Michael Gottesman
5acb6c939a [move-only] Perform an exclusive borrow when passing a var to a consuming var.
Consider the following example:

```
class Klass {}

@_moveOnly struct Butt {
  var k = Klass()
}

func mixedUse(_: inout Butt, _: __owned Butt) {}

func foo() {
    var y = Butt()
    mixedUse(&y, y)
}
```

In this case, we want to have an exclusivity violation. Before this patch, we
did a by-value load [copy] of y and then performed the inout access. Since the
access scopes did not overlap, we would not get an exclusivity violation.
Additionally, since the checker assumes that exclusivity violations will be
caught in such a situation, we convert the load [copy] to a load [take] causing
a later memory lifetime violation as seen in the following SIL:

```
sil hidden [ossa] @$s4test3fooyyF : $@convention(thin) () -> () {
bb0:
  %0 = alloc_stack [lexical] $Butt, var, name "y" // users: %4, %5, %8, %12, %13
  %1 = metatype $@thin Butt.Type                  // user: %3
  // function_ref Butt.init()
  %2 = function_ref @$s4test4ButtVACycfC : $@convention(method) (@thin Butt.Type) -> @owned Butt // user: %3
  %3 = apply %2(%1) : $@convention(method) (@thin Butt.Type) -> @owned Butt // user: %4
  store %3 to [init] %0 : $*Butt                  // id: %4
  %5 = begin_access [modify] [static] %0 : $*Butt // users: %7, %6
  %6 = load [take] %5 : $*Butt                    // user: %10                // <————————— This was a load [copy].
  end_access %5 : $*Butt                          // id: %7
  %8 = begin_access [modify] [static] %0 : $*Butt // users: %11, %10
  // function_ref mixedUse2(_:_:)
  %9 = function_ref @$s4test9mixedUse2yyAA4ButtVz_ADntF : $@convention(thin) (@inout Butt, @owned Butt) -> () // user: %10
  %10 = apply %9(%8, %6) : $@convention(thin) (@inout Butt, @owned Butt) -> ()
  end_access %8 : $*Butt                          // id: %11
  destroy_addr %0 : $*Butt                        // id: %12
  dealloc_stack %0 : $*Butt                       // id: %13
  %14 = tuple ()                                  // user: %15
  return %14 : $()                                // id: %15
} // end sil function '$s4test3fooyyF'
```

Now, instead we create a [consume] access and get the nice exclusivity error we
are looking for.

NOTE: As part of this I needed to tweak the verifier so that [deinit] accesses
are now allowed to have any form of access enforcement before we are in
LoweredSIL. I left in the original verifier error in LoweredSIL and additionally
left in the original error in IRGen. The reason why I am doing this is that I
need the deinit access to represent semantically what consuming from a
ref_element_addr, global, or escaping mutable var look like at the SIL level so
that the move checker can error upon it. Since we will error upon such
consumptions in Canonical SIL, such code patterns will never actually hit
Lowered/IRGen SIL, so it is safe to do so (and the verifier/errors will help us
if we make any mistakes). In the case of a non-escaping var though, we will be
able to use deinit statically and the move checker will make sure that it is not
reused before it is reinitialized.

rdar://101767439
2023-02-10 19:43:58 -08:00
Michael Gottesman
9e44011e4d [sil] Add a new attribute called @closureCaptured to SILFunctionArguments that are closure capture arguments.
I am adding this to make it easy to determine if a SILFunction that is not inout
aliasable is captured. This is useful when emitting certain types of
diagnostics like I need to emit with move only.
2022-12-14 15:16:43 -08:00
Michael Gottesman
0735f9f0bb [move-only] Teach SILGen that lets captured by a closure must be no copy.
The current diagnostic that we are emitting is not perfect, but at least this
prevents us from saying that an error is not occuring here. I am going to file a
bug to track the QoI work of improving the diagnostic.

rdar://103313305
2022-12-14 10:57:34 -08:00
Nate Chandler
3c78a0bb90 [SILGen] Only lexical types get lexical lifetimes.
Only emit `begin_borrow [lexical]` and only mark `alloc_stack`s
`[lexical]` when the variable in question's lifetime is lexical, not
eager move.
2022-08-22 15:28:00 -07:00
Meghana Gupta
196994fc11 Fix store_borrow generation in SILGen
This change ensures all store_borrows are ended with an end_borrow, and uses of the store_borrow
destination are all in the enclosing store_borrow scope and via the store_borrow return address.

Fix tests to reflect new store_borrow pattern
2022-08-16 15:08:22 -07:00
Michael Gottesman
9b625588f0 [sil] Make copyable_to_moveonlywrapper forwarding like moveonlywrapper_to_copyable.
Specifically this means that rather than always being owned, we now have owned
and guaranteed versions of copyable_to_moveonlywrapper. Similar to
moveonlywrapper_to_copyable, one chooses which variant one gets by using
specific SILBuilder APIs:
create{Owned,Guaranteed}CopyableToMoveOnlyWrapperValueInst. It is still
forwarding and the rest of the forwarding APIs work as expected except that the
forwarding ownership is fixed (and an assertion will result if one attempts to
do so).

NOTE: It is assumed that trivial operands are always passed to the owned
variant.
2022-07-19 14:39:59 -07:00
Michael Gottesman
4f8f5b6a84 [silgen] Add ManagedValue level APIs for creating CopyableToMoveOnlyWrapper and MarkMustCheck.
Just slimming down a larger commit.
2022-07-11 12:28:46 -07:00
Michael Gottesman
0d11e8ef69 [no-implicit-copy] Update SILGen/move checker to work with new patterns from copyable_to_moveonly and friends.
This involved doing the following:

1. Update the move only checker to look for new patterns.

2. Teach emitSemanticStore to use a moveonlywrapper_to_copyable to store moveonly
   values into memory. The various checkers will validate that this code is
   correct.

3. When emitting an apply, always unwrap move only variables. In the
   future, I am going to avoid this if a parameter is explicitly marked as also
   being moveonly (e.x.: @moveOnly parameter or @noEscape argument).

4. Convert from moveOnly -> copyable on return inst automatically in SILGen.

5. Fix SILGenLValue emission so we emit an error diagnostic later rather than
   crash. This is needed to keep SILGen emitting move only addresses (that is no
   implicit copy address only lets) in a form that the move only checker then
   will error upon. Without this change, SILGen crashes instead of emitting an
   error diagnostic in the following test:
   .//test/SILOptimizer/move_only_checker_addressonly_fail.swift
2022-06-21 16:47:58 -07:00
Andrew Trick
2fd4de411e [SIL-opaque] Removed [Unconditional]CheckedCastValue 2022-03-22 17:04:13 -07:00
Michael Gottesman
4cd1201bab [noImplicitCopy] Add support for marking a SILArgument as being a NoImplicitCopy argument.
I am purposely doing this in SILGen rather than at the type system level to
avoid having to have to add a bunch of boilerplate to the type system. Instead
of doing that, I am in SILGen checking for the isNoImplicitCopy bit on the
ParamDecl when we emit arguments. At that point, I set on the specific
SILArgument being emitted the bit that it is no implicit copy. In terms of
printing at the SIL level, I just printed it in front of the function argument
type like @owned, e.x.:

  func myFunc(_ x: @_noImplicitCopy T) -> T {
  ...
  }

becomes:

  bb0(%0 : @noImplicitCopy @owned $T):

Some notes:

* Just to be explicit, I am making it so that no implicit copy parameters by
  default are always passed at +1. The reason why I think this makes sense is
  that this is the natural way of working with a move only value.

* As always, one can not write no implicit copy the attribute without passing
  the flag -enable-experimental-move-only so this is NFC.

rdar://83957088
2021-11-01 09:34:38 -07:00
Michael Gottesman
f64180870a [silgen] When initializing tuples in SILGen, first evaluate all tuple elts and then perform sub-initialization.
Previsouly we were evaluating a tuple elt and then performing the relevant
sub-initialization. The problem is that a sub-initialization can invoke code
that could perform an early exit cleanup. So any later tuple-elements that may
need to be cleaned up along such path will not have had their cleanups
initialized, resulting in a leak along such paths.

With this commit, we instead evaluate all of the tuple elements and only them
perform the sub-initialization ensuring that any early exits clean up all of the
tuple elements.

rdar://83770295
2021-10-05 14:03:49 -05:00
Andrew Trick
8f53a927b0 SILGen OSSA support for switch_enum/checked_cast_br, related cleanup
Use APIs for creating terminator results that handle forwarding
ownership consistently.

Add ManagedValue::forForwardedRValue(SILValue) to handle cleanups
consistently based on ownership forwarding.

Add SILGenBuilder::createForwardedTermResult(SILType type) for
creating termator results with the correct ownership and cleanups.

Add SILGenBuilder::createTermResult(SILType type, ValueOwnershipKind
ownership) that handles cleanup based on terminator result ownership.

Add SILGenBuilder::createOptionalSomeResult(SwitchEnumInst) so a lot
of code doesn't need to deal with unwrapping Optional types,
terminator results, and ownership rules.

Replace the existing "phi" APIs with a single
SILGenBuilder::createPhi(SILType, ValueOwnershipKind) that handles
cleanup based on phi ownership.

Phis and terminator results are fundamentally different and need to be handled differently everywhere. Remove the confusion where terminator results were generated with a "phi argument" API.
2021-09-07 22:50:46 -07:00
Andrew Trick
5b37728f2a Fix OSSA in SILGenFunction::emitIVarDestroyer
It is illegal to borrow an unowned value. Unowned values are only
allowed to have specific instantaneous uses.

In this case, an unchecked conversion is valid because there is an
assumption that within a destructor, self is guaranteed.
2021-01-01 19:22:19 -08:00
Michael Gottesman
ac3109a21d [eager-specializer] Fix for ownership and add a bunch of missing code coverage for ossa.
Specifically, we were missing a bunch of coverage around specializing guaranteed
parameters and non-trivial values in general.
2020-07-09 21:46:19 -07:00
Michael Gottesman
0e985be3f4 [silgen] Create a function level scope when open coding implicit value initializers.
The Original Bug
----------------

In ffbfcfa131, we fixed a bug around implicit
value initializers but did not cherry-pick it to 5.3. While investigating a bug
that turned out to be that same bug (no worries!), I noticed that there is
additional code that is "unsafely" correct in this area and that while
ffbfcfa131 is correct in the small, we can expand
on the fix to prevent future bugs.

The Larger Bug
--------------

Here we are still open coding using ManagedValue/Cleanup APIs /without/ a top
level function scope. The code is only correct since we never emit unconditional
cleanups and always manually forward conditional cleanups. If we did not do
either of these things, we would have another instance of this bug, namely a
cleanup that is never actually emitted. So the code on master today is correct,
albeit unsafe, and we already have coverage for this (namely the test case from
ffbfcfa131).

That being said, in general when working with ManagedValue APIs (especially in
utility functions) we assume that we have a scope already created for us by our
caller. So by fixing this issue we are standardizing to safer SILGen invariants.

Building on ffbfcfa131
----------------------------------------------------

This commit builds on the shoulders of ffbfcfa131
by adding the function level scope mentioned in the previous section so that we
are now "safely" correct.

While looking at this I also realized that just using a normal scope when open
coding here may be a bit bugprone for open coding situations like this since:

1. If one just creates a scope in open coding situations, the scope will fire at
   end of the c++ function /after/ one has probably emitted a return.

2. Once one has emitted the return, the insertion point will no longer be set
   implying =><=.

To avoid this, I created a move only composition type on top of Scope called
AssertingManualScope. This type just asserts in its destructor if the scope it
contains has not been popped yet.

While, one can pop it by ones self, I added an overload of createReturnInst on
SILGenBuilder that also takes an AssertingManualScope and pops it at the
appropriate time.

So now when performing simple open coding tasks, we have the ability to in code
tie together the function level scope to the actual creation of return inst,
simulating the hand-off of lifetimes/resources from caller/callee that often
happens in the epilog of functions.

<rdar://problem/63189210>
2020-05-29 14:53:19 -07:00
Michael Gottesman
f3df836652 [ownership] Treat open_existential_box as an interior pointer producting instruction.
This means that it can only have a guaranteed object as an operandand that we
validate that all uses of the result address of open_existential_box occur only
within the lifetime of said object's borrow scope.
2020-03-15 23:21:45 -07:00
Michael Gottesman
f7f98887d4 [builtin] Add a new SIL builtin convertUnownedUnsafeToGuaranteed()
(BaseT, @inout @unowned(unsafe) T) -> @guaranteed T

The reason for the weird signature is that currently the Builtin infrastructure
does not handle results well. Also, note that we are not actually performing a
call here. We are SILGening directly so we can create a guaranteed result.

The intended semantics is that one passes in a base value that guarantees the
lifetime of the unowned(unsafe) value. The builtin then:

1. Borrows the base.
2. Loads the trivial unowned (unsafe), converts that value to a guaranteed ref
   after unsafely unwrapping the optional.
3. Uses mark dependence to tie the lifetimes of the guaranteed base to the
   guaranteed ref.

I also updated my small UnsafeValue.swift test to make sure we get the codegen
we expect.
2020-02-07 13:08:34 -08:00
Michael Gottesman
6c5c853339 [ownership] Change guaranteed args from transformation terminators to not require end_borrows.
For those who are unaware, a transformation terminator is a terminator like
switch_enum/checked_cast_br that always dominate their successor blocks. Since
they dominate their successor blocks by design and transform their input into
the args form, we can validate that they obey guaranteed ownership semantics
just like a forwarding instruction.

Beyond removing unnecessary code bloat, this also makes it significantly more
easier to optimize/work with transformation terminators when converting @owned
-> @guaranteed since we do not need to find end_borrow points when the owned
value is consumed.

<rdar://problem/59097063>
2020-02-02 16:59:57 -08:00
Slava Pestov
3997aa5754 SIL: Remove SILBuilder::tryCreateUncheckedRefCast() 2020-01-03 15:37:19 -05:00
Slava Pestov
53bfc767a3 SIL: Track target formal type for casts
SIL type lowering erases DynamicSelfType, so we generate
incorrect code when casting to DynamicSelfType. Fixing this
requires a fair amount of plumbing, but most of the
changes are mechanical.

Note that the textual SIL syntax for casts has changed
slightly; the target type is now a formal type without a '$',
not a SIL type.

Also, the unconditional_checked_cast_value and
checked_cast_value_br instructions now take the _source_
formal type as well, just like the *_addr forms they are
intended to replace.
2019-11-20 21:30:28 -05:00
Michael Gottesman
7ee5ad7318 [sil] Rename {,Strong}Copy{Unowned,Unmanaged}. 2019-10-26 17:03:47 -07:00
Michael Gottesman
6a54531811 [silgen] Add SILGen support for emitting copy_unmanaged_value instead of unmanaged_to_ref + strong_retain.
This will ensure that the optimizer never eliminates the strong_retain. This
operation is meant to be unmanaged, we should respect the user's choice here
even in optimized builds.
2019-08-26 09:40:27 -07:00
Slava Pestov
9a1abf705a SILGen: Remove SILGenSILBuilder
This reverts commit 59cc3c1216fbb1719e5357dcef3f8b249528fc74.
2019-04-25 02:06:14 -04:00
Michael Gottesman
3419662847 [silgen] Split off SILGenSILBuilder from SILGenBuilder and have SILGenBuilder inherit from it.
This prevents ManagedValue APIs on SILGenBuilder from by mistake accesing
non-conformance tracking APIs on SILBuilder.

NOTE: Eventually, we should make SILGenBuilder compose with SILGenSILBuilder and
then rename SILGenBuilder to ManagedValueBuilder. I did not do that in this PR
since it becomes very disruptive since there is still a lot of code in SILGen
that uses SILValue APIs and I have not found a concise way to write such
code. But this patch at least defines away this error which has bitten us
before.
2019-04-06 00:53:47 -07:00
Michael Gottesman
bec13367d2 [silgen] Eliminate some unneeded constructors from SILGenBuilder. 2019-04-05 12:49:19 -07:00
Arnold Schwaighofer
cb0c53abee SIL: Remove isEscapedByUser flag on convert_escape_to_noescape instruction
It was only used for materializeForSet and is now dead code.
2019-01-04 09:21:38 -08:00
Andrew Trick
f73e6c7adb Add a SILGenBuilder constructor that takes a new insertion point.
This is the best way to inherit the provided SILGenBuilder's debug
scope and context, but insert at a different SIL location.
2018-10-19 22:22:23 -07:00
Michael Gottesman
6b9986839c [silgen] Fix the ownership of enum element pattern initialization.
The problem here is that we were taking advantage of swift not-trashing the
original memory location after performing a load [take] to use load [take] as a
+0 load. This breaks the ownership verifier since the load [take] is never
actually destroyed. Instead this commit changes this code to use a load_borrow.

I found this when trying to enable ownership verification on
test/SILGen/indirect_enum.swift using some out of tree work that should have
fixed all of the ownership issues with SILGenPattern. Turns out I can just
enable ownership verification with just this change... so I did that as well in
this PR.

rdar://29791263
2018-10-14 15:39:49 -07:00
Michael Gottesman
d57a88af0d [gardening] Rename references to SILPHIArgument => SILPhiArgument. 2018-09-25 22:23:34 -07:00
Michael Gottesman
dfc3265f73 [silgen] Change SILGenPoly::executeInnerTuple to use destructures instead of tuple_extracts to element a borrow.
rdar://43493020
2018-08-20 18:10:17 -07:00
Michael Gottesman
a57ad403ec [silgen] Now that we have destructure, use it in RValue to reduce copies emitted by SILGen.
rdar://43493020
2018-08-20 08:52:51 -07:00
Andrew Trick
c9033ed938 Add a SIL attribute [without_actually_escaping].
ConvertFunction and reabstraction thunks need this attribute. Otherwise,
there is no way to identify that withoutActuallyEscaping was used
to explicitly perform a conversion.

The destination of a [without_actually_escaping] conversion always has
an escaping function type. The source may have either an escaping or
@noescape function type. The conversion itself may be a nop, and there
is nothing distinctive about it. The thing that is special about these
conversions is that the source function type may have unboxed
captures. i.e. they have @inout_aliasable parameters. Exclusivity
requires that the compiler enforce a SIL data flow invariant that
nonescaping closures with unboxed captures can never be stored or
passed as an @escaping function argument. Adding this attribute allows
the compiler to enforce the invariant in general with an escape hatch
for withoutActuallyEscaping.
2018-08-14 17:14:25 -07:00
John McCall
7a4aeed570 Implement generalized accessors using yield-once coroutines.
For now, the accessors have been underscored as `_read` and `_modify`.
I'll prepare an evolution proposal for this feature which should allow
us to remove the underscores or, y'know, rename them to `purple` and
`lettuce`.

`_read` accessors do not make any effort yet to avoid copying the
value being yielded.  I'll work on it in follow-up patches.

Opaque accesses to properties and subscripts defined with `_modify`
accessors will use an inefficient `materializeForSet` pattern that
materializes the value to a temporary instead of accessing it in-place.
That will be fixed by migrating to `modify` over `materializeForSet`,
which is next up after the `read` optimizations.

SIL ownership verification doesn't pass yet for the test cases here
because of a general fault in SILGen where borrows can outlive their
borrowed value due to being cleaned up on the general cleanup stack
when the borrowed value is cleaned up on the formal-access stack.
Michael, Andy, and I discussed various ways to fix this, but it seems
clear to me that it's not in any way specific to coroutine accesses.

rdar://35399664
2018-07-23 18:59:58 -04:00