Commit Graph

768 Commits

Author SHA1 Message Date
Pavel Yaskevich
135f2c2ea0 [SILGen] InitAccessors: Start supporting assign_or_init for properties without a setter
Implement "init accessor" component emission which is paired with
"init accessor" write strategy. Use `SILUndef` for a "setter" operand
of an "assign_or_init" instruction in cases when property with init
accessor doesn't have a setter. DI would detect re-initialization
attempts to produce diagnostics.
2023-07-03 22:07:19 -07:00
Pavel Yaskevich
511bd07574 [SILGen] InitAccessors: Split init accesssor handling into a separate component
The logic is going to be shared when we start supporting init accessor
properties without `set`.
2023-07-03 00:35:17 -07:00
Pavel Yaskevich
e49e4f985e [SILGen] NFC: Factor out logic from GetterSetterComponent to its base
Factor our following logic:

- Applying setter to its base value
- `newValue` emission

This would be useful for init accessor emission as well.
2023-06-30 11:48:08 -07:00
Pavel Yaskevich
fab9e4bc62 Merge pull request #66987 from xedin/refactor-init-accessors-to-carry-more-info
[SIL] InitAccessors: Refactor `assign_or_init` instruction to carry "self"
2023-06-30 11:46:01 -07:00
Pavel Yaskevich
80a1e2c2ba [SILGen] InitAccessors: Produce partial apply of init accessor ref to produce substituted closure
Instead of dealing with substitutions during raw SIL lowering,
let's produce a partial apply without argument to produce a
substituted reference that could be used by SILVerifier and
raw SIL lowering stages.
2023-06-28 12:28:15 -07:00
Pavel Yaskevich
3063e9d778 [SIL] InitAccessors: Reference "self" in assign_or_init instruction
First step on the path to remove dependence on "setter".
2023-06-27 09:45:05 -07:00
Evan Wilde
250082df25 [NFC] Reformat all the LLVMs
Reformatting everything now that we have `llvm` namespaces. I've
separated this from the main commit to help manage merge-conflicts and
for making it a bit easier to read the mega-patch.
2023-06-27 09:03:52 -07: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
Joe Groff
ca7b8e2890 Merge pull request #66445 from jckarter/noncopyable-computed-property-address-only-base
SILGen: Don't copy a borrowed noncopyable address-only base of a computed property access.
2023-06-08 13:42:41 -07:00
Joe Groff
f06621907e SILGen: Don't copy a borrowed noncopyable address-only base of a computed property access.
We can probably avoid this copy in more circumstances, but make the change only for
noncopyable types for now, since that's the case where it's most semantically apparent.
rdar://109161396
2023-06-08 08:36:04 -07:00
Pavel Yaskevich
7b140f89b9 [SILGen] InitAccessors: AssignOrInit instruction should reference init accessor directly
Previously init accessor has been partially applied just like a setter but
that is no loger valid now that it operates on individual field references.
2023-06-06 18:59:13 -07:00
Pavel Yaskevich
5bac6e8538 [SILGen] NFC: Generalize isCurrentFunction{{ReadAccess, InitAccessor}} functions 2023-06-06 18:59:13 -07:00
Pavel Yaskevich
00a9ccfcc3 [SILGen] InitAccessors: Remap property references into argument references
A reference to an instance property in init accessor body
has to be remapped into an argument reference because all
of the properties from initialized/accesses lists are passed
to init accessors individually via arguments.
2023-06-06 18:59:13 -07:00
Holly Borla
7512f6e366 [SIL] Add an assignment mode to AssignOrInitInst that will be set by DI. 2023-06-06 18:59:13 -07:00
Holly Borla
eb3ed2b374 [SILGen] Emit AssignOrInitInst for assignment to a computed property with
an init accessor inside of an initializer.
2023-06-06 18:59:13 -07:00
Holly Borla
684ef9c482 [AST] Add a new accessor kind for init accessors. 2023-06-06 18:57:31 -07:00
Michael Gottesman
59c8cff917 [borrowing] Add support for borrowing/consuming copyable types to be a noimplicitcopy type.
rdar://108383660
2023-06-06 18:12:29 -04:00
Michael Gottesman
5d9ab63dbb [move-only] When we emit a noncopyable temporary allocation, always attach a mark_must_check [consumable_and_assignable].
Most of the time SILGen already emits these correctly without having extra
copies, but in certain situations SILGen will emit copies that we need the move
checker to eliminate (e.x.: when we generate a yield). An additional benefit is
that this also will catch places where the frontend makes a mistake.

This also removes a bunch of "copy of noncopyable" types error that showed up in
the implicit compiler generated modify.
2023-05-25 14:57:55 -07:00
Michael Gottesman
fd25cf379a Rename MoveExpr -> ConsumeExpr to reflect the final name.
NFC.
2023-05-17 22:42:42 -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
e1f2a207bd Merge pull request #65604 from gottesmm/address-only-stuff
[move-only] Address Only Patches
2023-05-03 18:39:25 -07:00
Michael Gottesman
20958c90b5 [move-only] Add initial support for address only types.
Specifically, I changed emitRValueForDecl and SILGenProlog to do the right
thing. I also added some tests.

Some notes:

1. We currently consider using a copyable field of a move only address type to
be a consume of that type. I am going to fix that in the next commit to make it
easier to understand.

2. I am going to need to write more tests/flesh out the behavior more. I am sure
there is more here.

rdar://105106470
2023-05-02 16:30:24 -07:00
Andrew Trick
ea7b8055bc Rewrite some isPlusOne calls to isPlusOneOrTrivial.
Whenever we want to forward to a +1 value but don't need to destroy
the original memory, use isPlusOneOrTrivial.

This follows the existing naming scheme.

Fixes rdar://108001491 (SIL verification failed: Found mutating or
consuming use of an in_guaranteed parameter?!:
!ImmutableAddressUseVerifier().isMutatingOrConsuming(fArg))
2023-05-01 23:24:29 -07:00
Michael Gottesman
9a0b9665f1 [move-only] When emitting accesses to let boxes containing a noncopyable type, always emit mark_must_check.
The reason to do this is that:

1. Otherwise, we do not emit markers when someone attempts to consume the let.
We need the no_consume_or_assign to be there.
2. We need to insert assign_but_not_consuming so that DI can properly check lets
that are conditionally initialized and convert them to
initable_but_not_consuming.

I included a full definite_init SIL test that validates that we get the correct
codegen after DI in this case and emit the appropriate error as well.

rdar://108511534
2023-04-25 10:51:04 -07:00
Michael Gottesman
9252d5ea8b [move-only] Eliminate dead code that was not removed when re-projected move only types were removed. 2023-04-25 10:51:03 -07:00
Joe Groff
cb23187209 SILGen: Emit move-only bases for lvalues in a borrow scope.
Normally, if we project from a mutable class ivar or global variable, we'll
load a copy in a tight access scope and then project from the copy, in order to
minimize the potential for exclusivity violations while working with classes and
copyable values. However, this is undesirable when a value is move-only, since
copying is not allowed; borrowing the value in place is the expected and only possible
behavior. rdar://105794506
2023-04-19 14:50:34 -07:00
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