Commit Graph

742 Commits

Author SHA1 Message Date
Adrian Prantl
829491b230 Merge pull request #64551 from adrian-prantl/88274783
Rebase SILScope generation on top of ASTScope
2023-04-05 08:30:13 -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
John McCall
9c9671b349 Merge pull request #64887 from rjmccall/vanishing-tuple-silgen
SILGen and SIL type lowering support for vanishing tuples
2023-04-04 12:41:29 -04:00
John McCall
5942049c83 Set substitutions on storage abstraction patterns in l-value access.
Fixes a host of problems with stored type members with types dependent
on a type parameter pack; I ran into it specifically with vanishing
tuples.

Test to follow.
2023-04-03 23:09:36 -04:00
Joe Groff
8e21bfcc47 MoveOnlyAddressChecker: Confine analysis to current formal access.
Code can only locally interact with a mutable memory location within a
formal access, and is only responsible for maintaining its invariants
during that access, so the move-only address checker does not need to,
and should not, observe operations that occur outside of the access
marked with the `mark_must_check` instruction. And for immutable
memory locations, although there are no explicit formal accesses, that's
because every access must be read-only, so although individual
accesses are not delimited, they are all compatible as far as
move-only checking is concerned. So we can back out the changes to SILGen
to re-project a memory location from its origin on every access, a
change which breaks invariants assumed by other SIL passes.
2023-04-02 16:33:57 -07:00
Michael Gottesman
02a12d4142 [move-only] Make sure to treat ref_element_addr mutable address accesses similar to inout.
I also slightly changed the codegen around where we insert the mark_must_check.
Specifically, before we would emit the mark_must_check directly on the
ref_element_addr and then insert the access. This had the unfortunate effect
that we would hoist any destroy_addr that were actually needed out of the access
scope. Rather than do that, I now insert the mark_must_check on the access
itself. This results in the destroy_addr being within the scope (like the
mark_must_check itself).

rdar://105910066
2023-03-14 14:03:20 -07:00
Holly Borla
dce70f373f [SILGen] Emit MaterializePackExprs.
The subexpression of a MaterializePackExpr (which is always a tuple value
currently) is emitted while preparing to emit a pack expansion expr, and its
elements are projected from within the dynamic pack loop. This means that a
materialized pack is only evaluated once, rather than being evaluated on
every iteration over the pack elements.
2023-03-09 21:44:03 -08:00
John McCall
157be3420c Implement the callee side of returning a tuple containing a pack expansion.
This required quite a bit of infrastructure for emitting this kind of
tuple expression, although I'm not going to claim they really work yet;
in particular, I know the RValue constructor is going to try to explode
them, which it really shouldn't.

It also doesn't include the caller side of returns, for which I'll need
to teach ResultPlan to do the new abstraction-pattern walk.  But that's
next.
2023-03-06 04:26:18 -05:00
John McCall
06a7468e4f Implement the emission of pack expansion arguments in SILGen
Mostly fixing some existing code.
2023-03-03 02:52:32 -05:00
John McCall
fb9578133b Steps towards supporting pack expansions properly in signature
lowering and argument emission.

Pack expansions in argument emission don't work yet, but I wanted
to land this bit of incremental progress.
2023-02-24 18:34:52 -05:00
Michael Gottesman
1dd896ded9 [move-only] Implement escaping closure semantics.
NOTE: A few of the test patterns need to be made better, but this patch series
is large enough, I want to get it into tree and iterate.
2023-02-20 11:04:21 -08:00
Michael Gottesman
f4e1b2a8f2 [move-only] Update SILGen/MoveCheckers so that vars are emitted in eagerly projected box form.
This is the first slice of bringing up escaping closure support. The support is
based around introducing a new type of SILGen VarLoc: a VarLoc with a box and
without a value. Because the VarLoc only has a box, we have to in SILGen always
eagerly reproject out the address from the box. The reason why I am doing this
is that it makes it easy for the move checker to distinguish in between
different accesses to the box that we want to check separately. As such every
time that we open the box, we insert a mark_must_check
[assignable_but_not_consumable] on that project. If allocbox_to_stack manages to
determine that the box can be stack allocated, we eliminate all of the
mark_must_check and place a new mark_must_check [consumable_and_assignable] on
the alloc_stack.  The end result is that we get the old model that we had before
and also can support escaping closures.
2023-02-20 11:04:21 -08:00
Michael Gottesman
c832b41b7b [move-only] Teach the move checker how to handle global_addr.
As part of this I also had to change how we emit global_addr in
SILGenLValue. Specifically, only for noncopyable types, we no longer emit a
single global_addr at the beginning of the function (in a sense auto-CSEing) and
instead always emit a new global_addr for each access. The reason why we do this
is that otherwise, access base visitor will consider all accesses to the global
to be for the same single access. In contrast, by always emitting the
global_addr each time, we provide a new base for each access allowing us to emit
the diagnostics that we want to.

rdar://102794400
2023-02-12 17:39:27 -08:00
Michael Gottesman
e58c45fa1e [move-only] Add support for ref_element_addr with AssignableButNotConsumable semantics.
rdar://104874497
2023-02-12 17:39:27 -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
Pavel Yaskevich
e0bf2ff854 [SIL/DI] NFC: Remove TypeWrappers feature functionality 2023-02-08 10:14:29 -08:00
Michael Gottesman
d909c8978e [no-implicit-copy] When accessing a field from a no-implicit-copy struct, unwrap it. Also do not run the move only borrow to destructure transform error.
The reason to do the first is to ensure that when I enable -sil-verify-all, we
do not have errors due to a copy_value of a move only type.

The reason to do the second thing is that:

1. If we have a move only type that is no implicit copy, I am in a subsequent
commit going to emit a type checker error saying that one cannot do this. When
we implement consuming/borrowing bindings/etc, we can make this looser if it
gets into the way.

2. If we have a copyable no implicit copy type, then any structural accesses
that we may want to do that would require a destructure must be to a copyable
type which is ok to copy as long as we do the unwrap from the first thing.

rdar://104929957
2023-02-01 14:48:45 -08:00
Meghana Gupta
9dceb378e0 Merge pull request #63259 from meg-gupta/ptrauthaddrdiversified1
Initial support for importing address diversified pointer auth qualified field function pointers
2023-01-27 13:58:44 -08:00
Meghana Gupta
1dac5d48d3 Support for address discriminated pointers 2023-01-27 01:56:44 -08:00
Allan Shortlidge
8a18fc0fa9 Merge pull request #63229 from tshortli/avoid-unnecessary-back-deploy-thunk
SILGen: Avoid using back deployment thunks for high enough deployment targets
2023-01-26 15:40:43 -08:00
Allan Shortlidge
80295fdaa1 SILGen: Avoid using back deployment thunks for high enough deployment targets.
If a function body references a declaration with the `@_backDeploy(before:)` attribute and that function body will only execute on deployment targets for which the ABI version of the decl is available then it is unnecessary to thunk the reference to the decl. Function bodies that may be emitted into other modules (e.g. `@inlinable`) must always use the thunk.

Resolves rdar://90729799
2023-01-25 17:22:23 -08:00
Meghana Gupta
25d83406ad Generate begin_access [signed] when handling a field function pointer with __ptrauth qualifier 2023-01-25 14:03:19 -08:00
Nate Chandler
cd03615a1a [OpaqueValues] Initial key-path support.
Enough support for emitting key-paths SIL to build _Regex and
_StringProcessing.
2022-12-13 18:06:56 -08:00
Joe Groff
d9c4bed487 Merge pull request #62312 from jckarter/mix-read-or-address-with-setter-reabstraction
SILGen: Match up abstraction level when materializing mixed set and read/unsafeAddress properties.
2022-11-30 14:51:22 -08:00
Joe Groff
d1a9f9a6b3 SILGen: Match up abstraction level when materializing mixed set and read/unsafeAddress properties.
Addresses part of rdar://102525437.
2022-11-29 21:24:32 -08:00
Erik Eckstein
ab1b343dad use new llvm::Optional API
`getValue` -> `value`
`getValueOr` -> `value_or`
`hasValue` -> `has_value`
`map` -> `transform`

The old API will be deprecated in the rebranch.
To avoid merge conflicts, use the new API already in the main branch.

rdar://102362022
2022-11-21 19:44:24 +01:00
swift-ci
fd6fd76dae Merge pull request #42513 from jsoref/spelling-silgen
Spelling silgen
2022-11-09 23:28:43 -08:00
Josh Soref
9a6bf46c0f Spelling silgen
* actually
* arbitrary
* cargo-culted
* clazz
* constrained
* continuation
* coordinator
* coroutine
* derivative
* destroyer
* given
* have
* imported
* initialization
* items
* necessarily
* occurring
* omitting
* overridden
* parameter
* possible
* predecessor
* preparation
* resilience
* should
* struct
* that
* the
* throwing
* unexpectedly
* uniqueness
* using
* value
* villain

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>
2022-11-09 21:44:17 -05:00
Michael Gottesman
26db1f20a3 [move-only] Emit a copy_addr instead of a mark_unresolved_move_addr when applying the move operator to move only vars.
The reason why we are doing this is that we want move only addresses to be
checked by the move only address checker and not the move operator address
checker.

rdar://102056097
2022-11-07 14:29:03 -08:00
Amritpan Kaur
fd31b663dd [LValue] Move PhysicalPathComponent tail assign into set method. 2022-11-02 08:53:28 -07:00
Pavel Yaskevich
31cf06b717 [SILGen] TypeWrappers: Route property wrapper through _storage for managed properties
When property has attached property wrappers and is managed
by a type wrapper at the same time it has to be initialized in
a special way - instead of using backing property directly
(which is not actually a stored property in this scheme)
`assign_by_wrapper` instruction has to use a field of a
local `_storage` variable which represents underlying storage
before `$storage` property could be initialized.
2022-09-29 20:50:37 -07:00
Pavel Yaskevich
71eb2a7397 [SILGen] Start emitting assign_by_wrapper for type wrappers
Properties that are managed by a type wrapper have to be initialized
through a temporary `_storage` variable and only DI can tell us
when `_storage` is fully initialized, so we need to emit a
`assign_by_wrapper` instruction (with originator - type wrapper)
for every assignment to keep that and inject `$_storage.init`
as soon as all the managed properties are initialized.
2022-09-29 20:50:36 -07:00
Pavel Yaskevich
df87a494c2 [SIL] Add originator to assign_by_wrapper instruction
Originator of this temporary instruction could be either
type or property wrapper.
2022-09-29 20:50:36 -07:00
Kavon Farvardin
0eb69d3f0c model the ABISafeConversionComponent as a translation component, rather than physical
Also renaming it to be UncheckedConversionComponent since it's a better name.

As a physical component, we'd run into problems in assignment statements.
The problem was that if we had something like:

```
SomeOtherComponent          // first component
GetterSetterComponent
ABISafeConversionComponent  // last component
```

When emitting the assignment, we always drill down through all but
the last component by calling `project()` on each one. Then on the last
component, we'd do the actual setting operation. But GetterSetterComponent
cannot be projected when the access is for writing.

So, to work around this I decided to model it as a TranslationComponent, because
those are specifically designed to be handled during an assignment by popping those
off the end of the component sequence, untranslating the value we're about to assign
as we go, until we hit the GetterSetterComponent.

By "untranslating" we're effectively putting Sendable back onto the set's argument
prior to calling set, because the underlying property's type still has `@Sendable`
on it (e.g., it's accessors still have that on its argument type). When
"translating" we're effectively taking Sendable off after reading it.

I think actually works really well and makes much more sense now.

resolves rdar://99619834
2022-09-13 13:07:21 -07:00
swift-ci
a66951aa3d Merge pull request #60521 from kavon/preconcurrency-var-access
Add missing function conversion for member access to preconcurrency vardecl.
2022-08-30 00:58:49 -07:00
Kavon Farvardin
6c24bc57cb [AST][SILGen] model ABI-safe casts of LValues
We needed a way to describe an ABI-safe cast of an address
representing an LValue to implement `@preconcurrency` and
its injection of casts during accesses of members.

This new AST node, `ABISafeConversionExpr` models what is
essentially an `unchecked_addr_cast` in SIL when accessing
the LVAlue.

As of now I simply implemented it and the verification of
the node for the concurrency needs to ensure that it's not
misused by accident. If it finds use outside of that,
feel free to update the verifier.
2022-08-29 20:58:26 -07:00
Doug Gregor
5191c315e1 Eliminate ImplicitActorHopTarget in favor of ActorIsolation.
The generalized ActorIsolation is enough to represent everything that
ImplicitActorHopTarget can do, and we were mapping between the two way
too often, so collapse them.
2022-08-23 23:19:46 -07:00
Michael Gottesman
6493886e1d [move-keyword] Wire up support for the move keyword in lvalue/rvalue emission.
I also updated the move function tests to show that this is working. As a nice
bonus, I was able to enable all of the tests also in a non-optimized stdlib.
2022-08-08 12:50:42 -07:00
Michael Gottesman
f1182a73da [no-implicit-copy] Remove auto +1 param signature change called by noimplicit copy in favor of following normal convention.
I also added a bunch of tests for both the trivial/non-trivial case as well as
some docs to SIL.rst.
2022-07-19 16:39:03 -07:00
Doug Gregor
bc8bd4ea60 Emit actor hop as part of call to the getter.
When emitting a call to the getter for storage, emit the actor hop (and
hop back) as part of the call itself, rather than around the whole
initialization. This address a bug involving initialization with an
optional binding in an `if let`, where the hop-back would only be
performed on the non-nil branch.

Fixes rdar://96487805 / FB10562197
2022-07-06 13:14:50 -07:00
Konrad `ktoso` Malawski
ef525424f6 Merge pull request #59700 from xedin/distributed-computed-properties-via-accessor-thunk
[Distributed] Implement distributed computed properties via special accessor
2022-06-30 16:04:36 +09:00
Pavel Yaskevich
2480c99dee [Distributed] Generate thunk for accessor as a regular method
It used to be an accessor but that is not required because
SILDeclRef controls mangling which is the most imprortant
and could be used to emit the right reference.
2022-06-29 17:57:58 -07:00
Pavel Yaskevich
59ec5ab552 [Distributed] SILGen: Remove isDistributed flags from accessor code 2022-06-29 14:49:10 -07:00
Pavel Yaskevich
e8987b4c3e [Distributed] Add a new access strategy - DispatchToDistributedThunk
This strategy is used to dispatch accesses to 'distributed' computed
property to distributed thunk accessor instead of a regular getter
when access happen outside actor isolation context.
2022-06-29 14:49:10 -07:00
Pavel Yaskevich
5bdf94f346 [Distributed] Remove commented out code and print statements 2022-06-29 14:49:10 -07:00
Konrad `ktoso` Malawski
febfef97d4 [Distributed] Skeleton implementation of distributed computed properties 2022-06-29 14:49:04 -07:00
Michael Gottesman
6a24087f90 Merge pull request #59611 from gottesmm/moveonly-rebase
[no-implicit-copy] Update SILGen/move checker to work with new patterns from copyable_to_moveonly and friends.
2022-06-28 13:45:15 -07:00
Konrad `ktoso` Malawski
6a2778645f Revert "Merge pull request #59481 from xedin/distributed-computed-properties"
This reverts commit 8125a85a8f, reversing
changes made to 728971c5b7.
2022-06-25 08:49:00 +09: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
Pavel Yaskevich
6e1a44dfdc [SILGen] NFC: Remove an unused var left by distributed actor changes 2022-06-21 10:34:59 -07:00