Commit Graph

2864 Commits

Author SHA1 Message Date
Erik Eckstein
6b1697eb06 use new llvm::Optional APIs to fix deprecation warnings 2023-06-28 14:28:38 +02:00
Michael Gottesman
bd90e310e1 Merge pull request #66952 from gottesmm/pr-87fcc78991b465d8a15454dc76b66d6f347ddff0
[move-only] Emit an error if we /ever/ partially consume a noncopyable type.
2023-06-28 01:00:40 -07:00
Michael Gottesman
e1ab0eb93d Merge pull request #66969 from gottesmm/pr-4c80b1d0ebd95ec75ce40df2b5e5790cf9c9941c
[move-only] When storing a trivial field of a borrowed parameter, treat the store as a trivial use.
2023-06-28 00:17:55 -07:00
Michael Gottesman
6e850d7bce [move-only] When storing a trivial field of a borrowed parameter, treat the store as a trivial use.
rdar://111354827
2023-06-27 17:08:48 -07:00
Michael Gottesman
3dde9df468 [move-only] Emit an error if we /ever/ partially consume a noncopyable type.
The reason why I am doing this is that this was not part of the original
evolution proposal (it was called an extension) and after some discussion it was
realized that partial consumption would benefit from discussion on the forums.

rdar://111353459
2023-06-27 13:52:49 -07:00
Michael Gottesman
170ba67bd3 [move-only] Eliminate some temporary copies inserted by SILGen when accessing fields of lets.
In the next commit, I am modifying the move only checker to ensure that we
always error when partially invalidating. While doing this I discovered that
these copies were getting in the way of emitting good diagnostics in that case.
2023-06-27 13:41:31 -07:00
Nate Chandler
d00da4a0c1 [MoveOnlyAddressChecker] Fix repr for initInsts.
The address checker records instructions that initialize fields in its
initInsts map.  Previously, that map mapped from an instruction to a
range of fields of the type.  But an instruction can initialize multiple
discontiguous fields of a single value.  (Indeed an attempt to add a
second range that was initialized by an already initializing
instruction--even if it were overlapping or adjacent--would have no
effect and the map wouldn't be updated.)  Here, this is fixed by fixing
the representation and updating the storage whenver a new range is seen
to be initialized by the instruction.  As in
https://github.com/apple/swift/pull/66728 , a SmallBitVector is the
representation chosen.

rdar://111391893
2023-06-27 12:10:52 -07:00
Nate Chandler
f7f5802664 [MoveOnlyAddressChecker] NFC: Extracted helpers.
In preparation for having a third instance getting or creating the bits
affected by an instruction, introduce a typealias for maps
SILInstruction->SmallBitVector and a helper function that returns
a reference to the SmallBitVector for an instruction and two others that
set into those bits the bits from another bit vector or from a range.
2023-06-27 12:10:52 -07:00
Nate Chandler
4a5009a612 [MoveOnlyAddressChecker] Fix repr for reinits.
The address checker records instructions that reinit fields in its
reinitInsts map.  Previously, that map mapped from an instruction to a
range of fields of the type.  But an instruction can use multiple
discontiguous fields of a single value.  (Indeed an attempt to add a
second range that was reinit'd by an already reinit'ing
instruction--even if it were overlapping or adjacent--would have no
effect and the map wouldn't be updated.)  Here, this is fixed by fixing
the representation and updating the storage whenver a new range is seen
to be reinit'd by the instruction.  As in
https://github.com/apple/swift/pull/66728 , a SmallBitVector is the
representation chosen.

rdar://111356251
2023-06-27 12:10:52 -07:00
Nate Chandler
50798ff67e [MoveOnlyAddressChecker] NFC: Extracted function.
In preparation to share the getOrCreateConsumingBlock functionality with
another overload of recordConsumingBlock.
2023-06-27 11:24:47 -07:00
Nate Chandler
eb698970dd [MoveOnlyAddressChecker] NFC: Used helper.
Used the TypeTreeLeafTypeRange::setBits helper rather than looping over
the range and setting the bits in place.
2023-06-27 11:24:47 -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
nate-chandler
98d895db52 Merge pull request #66892 from nate-chandler/rdar111221183
[MoveOnlyAddressChecker] Fixed two use-before-def handlings.
2023-06-23 19:13:56 -07:00
Nate Chandler
ff7aa3c99a [LifetimeExtension] Fixed reinit collection.
During initializeLiveness, all blocks which contain destroys are to be
recorded in consuming blocks.  Previously, however, certain reinits were
not being added.  Here, all reinits are correctly added.
2023-06-23 12:50:05 -07:00
Nate Chandler
8eff2e8299 [LifetimeExtension] Handle use-before-def.
The multi-def algorithm is based off the single-def algorithm.  However,
it differs from it in needing to handle "liveness holes"--uses before defs.

When identifying blocks which are originally live, the algorithm starts
from consuming blocks and walks backwards until a condition is met.

Previously, that condition was finding blocks which were originally
live.  That makes sense in the single-def case: if a block is originally
live, either it was already walked through or else it was one of the
blocks discovered by liveness.  In either case, its predecessors have
already been visited if appropriate.

However, in the multi-def case, this condition is too stringent.  It
fails to account for the possibility of a block with has a "liveness
hole".  Only stop the backwards walk if the predecessor not only (1) was
in originally live but additionally (2) "kills liveness"--doesn't have a
use before a def.

rdar://111221183
2023-06-23 12:50:04 -07:00
swift-ci
0f201443ac Merge pull request #66846 from kavon/standardize-workqueue
Add a `BasicBlockWorkqueue` as a common utility.
2023-06-22 04:26:34 -07:00
Kavon Farvardin
ba885d9ec2 rewrite emitMissingConsumeInDiscardingContext to use BasicBlockWorkqueue 2023-06-21 23:40:08 -07:00
Kavon Farvardin
51eaf4a1e5 rewrite findNonisolatedBlame to use BasicBlockWorkqueue
also simplifies the logic of the search quite a bit.
2023-06-21 23:40:08 -07:00
Meghana Gupta
03b8c49371 Merge pull request #66645 from meg-gupta/mixinremovesmall
Simplify forwarding instruction definitions in SIL
2023-06-21 13:02:13 -07:00
Michael Gottesman
b8a4132af7 Merge pull request #66783 from gottesmm/pr-9c93f4322f46013f6053b162d35adfe4b4252b8f
[move-only] Remove use after move in CopiedLoadBorrowEliminationVisitor.
2023-06-21 10:53:55 -07:00
Joe Groff
282a9a7364 Merge pull request #66792 from jckarter/nonescaping-closure-conversion-moveonly-checker
MoveOnlyChecker: Look through `convert_function` of nonescaping closures.
2023-06-21 09:36:33 -07:00
Joe Groff
26d8d84270 Merge pull request #66651 from jckarter/noncopyable-address-only-borrowed-capture
ClosureLifetimeFixup: Remove copy of borrowed move-only nonescaping captures when possible.
2023-06-21 09:36:18 -07:00
Erik Eckstein
bfb5d21312 PerformanceDiagnostics: fix two small issues which result in false alarms
* Look through `begin_borrow` when analyzing closure values
* Treat non-escaping closures as trivial values when passed to a `partial_apply`

rdar://111046264
2023-06-21 12:46:39 +02:00
Joe Groff
8f30a0097a MoveOnlyChecker: Look through convert_function of nonescaping closures.
Like a nested partial_apply reabstraction, but without the thunk, these change
the representation of the function but can't escape it without breaking the
nonescaping closure promotion. rdar://111060678
2023-06-20 18:20:45 -07:00
Michael Gottesman
b4092c4572 [move-only] Remove use after move in CopiedLoadBorrowEliminationVisitor.
Specifically, we were calling process on a visitor that was already moved. To
fix this I created a separate state structure that the visitor initializes and
moved the post-processing step onto the state data structure.

This seems to not be causing any problems today, but could in the future.

rdar://111060475
2023-06-20 13:36:10 -07:00
Joe Groff
ed2cbca04f ClosureLifetimeFixup: Remove copy of borrowed move-only nonescaping captures when possible.
SILGen introduces a copy of the capture, because the semantics of escaping partial_apply's
requires the closure to take ownership of the parameters. We don't know when a closure is
strictly nonescaping or its final lifetime until ClosureLifetimeFixup runs, but that replaces
the consume of the copy with a borrow of the copy normally, hoping later passes fix it up.
We can't wait that long for move-only types, which can't be copied, so try to remove the
copy up front when the copy lives long enough and has no interfering uses other than the
partial_apply. rdar://110137169
2023-06-20 12:10:31 -07:00
Andrew Trick
1790ca2292 Merge pull request #66691 from atrick/fix-field-liveness
Fix MoveOnlyAddressChecker to handle value deinits.
2023-06-20 12:04:43 -07:00
Joe Groff
c7d6821f4f Merge pull request #66726 from jckarter/disallow-dynamic-move-only-definite-init
DefiniteInitialization: Error when noncopyable types are conditionally initialized.
2023-06-20 09:57:52 -07:00
Andrew Trick
a8c45c55c4 Fix MoveOnlyAddressChecker to handle value deinits.
Track liveness of self so we don't accidentally think that such types
can be memberwise reinitialized.

Fixes rdar://110232973 ([move-only] Checker should distinguish in
between field of single field struct vs parent field itself (was:
mutation of field in noncopyable struct should not trigger deinit))
2023-06-19 18:38:03 -07:00
swift-ci
bbed05b9e6 Merge pull request #66728 from nate-chandler/rdar110676577_2
[MoveOnlyAddressChecker] Fix representation for used fields.
2023-06-17 20:31:06 -07:00
Nate Chandler
66867c02d1 [MoveOnlyAddressChecker] Fix used fields repr.
The address checker records uses in its livenessUses map.  Previously,
that map mapped from an instruction to a range of fields of the type.
But an instruction can use multiple discontiguous fields of a single
value.  Here, such instructions are properly recorded by fixing the map
to store a bit vector for each instruction.

rdar://110676577
2023-06-17 16:04:43 -07:00
nate-chandler
d3125898ae Merge pull request #66585 from nate-chandler/rdar99681073
[MoveOnlyAddressChecker] Maximize lifetimes.
2023-06-17 14:00:38 -07:00
nate-chandler
91ee8249d3 Merge pull request #66690 from nate-chandler/rdar110676577
[FieldSensitivePL] Fix vectorization.
2023-06-17 13:44:42 -07:00
Nate Chandler
2bfa723951 [MoveOnlyAddressChecker] Added extension flag.
Passing

```
-Xllvm -move-only-address-checker-disable-lifetime-extension=true
```

will skip the maximization of unconsumed field lifetimes.
2023-06-16 21:13:10 -07:00
Nate Chandler
11443f26ed [move-only] Avoid loc from func decl.
It's always the first line of the function, so try to do better.
2023-06-16 21:13:09 -07:00
Nate Chandler
eaf4560cd7 [MoveOnlyAddressChecker] Maximize lifetimes.
Previously, the checker inserted destroys after each last use.  Here,
extend the lifetimes of fields as far as possible within their original
(unchecked) limits.

rdar://99681073
2023-06-16 21:13:09 -07:00
Nate Chandler
b97712c422 [MoveOnlyAddressChecker] NFC: Promoted assertion.
Dumped more info and called llvm_unreachable on bad state.
2023-06-16 21:13:09 -07:00
Nate Chandler
f4e3292a2f [FieldSensitivePL] Fix vectorization.
FieldSensitivePrunedLiveness is used as a vectorization of
PrunedLiveness.  An instance of FSPL with N elements needs to be able to
represent the same states as N instances of PL.

Previously, it failed to do that in two significant ways:

(1) It attempted to save space for which elements were live by using
    a range.  This failed to account for instructions which are users of
    non-contiguous fields of an aggregate.

    apply(
      @owned (struct_element_addr %s, #S.f1),
      @owned (struct_element_addr %s, #S.f3)
    )

(2) It used a single bit to represent whether the instruction was
    consuming.  This failed to account for instructions which consumed
    some fields and borrowed others.

    apply(
      @owned (struct_element_addr %s, #S.f1),
      @guaranteed (struct_element_addr %s, #S.f2)
    )

The fix for (1) is to use a bit vector to represent which elements
are used by the instruction.  The fix for (2) is to use a second bit
vector to represent which elements are _consumed_ by the instruction.

Adapted the move-checker to use the new representation.

rdar://110909290
2023-06-16 21:13:07 -07:00
Joe Groff
40ad5aaffc DefiniteInitialization: Error when noncopyable types are conditionally initialized.
This leads to unhandled complications in the move-only checker that were causing miscompiles.
We can disallow this for now. rdar://109695770
2023-06-16 17:13:38 -07:00
Erik Eckstein
fe87b99e4d PerformanceDiagnostics: when checking closure values, look through convert_function 2023-06-15 21:42:01 +02:00
Meghana Gupta
16c300c2af Remove OwnershipForwardingConversionInst, ConversionInst.
Add new ConversionOperation abstraction, use this in place of ConversionInst
2023-06-15 10:53:28 -07:00
Meghana Gupta
7cb3733e29 Rename OwnershipForwardingMixin -> ForwardingInstruction 2023-06-14 10:40:32 -07:00
Pavel Yaskevich
2b8a39724c Merge pull request #66513 from xedin/init-accessor-diagnostics
[Sema/SIL] Improve diagnostics related to init accessors
2023-06-14 09:57:08 -07:00
Erik Eckstein
63808be395 DefinitInitialization: convert begin_access instructions of initializations to a static accesses
In case of `var` initializations, SILGen creates a dynamic begin/end_access pair around the initialization store.
If it's an initialization (and not a re-assign) it's guanranteed that it's an exlusive access and we can convert the access to an `[init] [static]` access.

https://github.com/apple/swift/issues/66496
2023-06-14 07:17:56 +02:00
Meghana Gupta
5d401fb70a Remove select_value SIL instruction 2023-06-13 14:13:43 -07:00
Pavel Yaskevich
f6fd0bc1a7 [DI] InitAccessors: Enforce that @out parameters are fully initialized before every terminator
This closes a hole where an early return could leave some
properties from `initializes(...)` list uninitialized.

For example:

```swift
init(initialValue) initializes(_a, _b) {
  _a = initialValue.0
  if _a > 0 {
    return
  }

  _b = initialValue.1
}
```

Here `_b` is not initialized when `_a > 0`.
2023-06-13 10:58:50 -07:00
Kavon Farvardin
219f94fd1a tailor reinit-after-consume message for closure captures
rdar://109908383
2023-06-12 21:04:25 -07:00
Michael Gottesman
97e6b56456 Merge pull request #66402 from gottesmm/main-rdar110364874
[borrowing/consuming] Be sure to visit boxes with trivial @moveonly types.
2023-06-07 14:42:25 -04:00