Commit Graph

54 Commits

Author SHA1 Message Date
Kavon Farvardin
fd06bb1eeb DebugInfo: fix FSPL SILLocation assertion issue
We were reusing the SILLocation from return instructions
to generate projections to ultimately destroy values.

This fix improves on what we were doing before, by
converting the insertion point's SILLocation into a
RegularLocation _without dropping_ the source location.

If the SILLocation was tied to an ASTNode, it'll carry
over the line location for this new regular location.
Otherwise, it'll fallback to the prior strategy of
producing a line 0 autogenerated location.

resolves rdar://163281183
2025-10-24 11:57:34 -07:00
Slava Pestov
4a63007414 SIL: Don't ask for stored properties of resilient types in TypeSubElementCount::TypeSubElementCount 2025-10-15 13:44:42 -04:00
nate-chandler
b93ed3e32b Merge pull request #81081 from swiftlang/revert-80839-moveonly-trivial-field-as-reinitialize
Revert "MoveOnlyChecker: Treat trivial stores as reinitializations rather than initializations."
2025-04-24 19:34:08 -07:00
nate-chandler
e4d3207b40 Revert "MoveOnlyChecker: Treat trivial stores as reinitializations rather than initializations." 2025-04-24 12:10:07 -07:00
Nate Chandler
02cad73cef [FSPL] Look through unchecked addr casts.
rdar://149850921
2025-04-23 21:29:22 -07:00
Joe Groff
a1ff2e38dc MoveOnlyChecker: Treat trivial stores as reinitializations rather than initializations.
A trivial store is allowed to occur on an existing live value, and should not
trigger an attempt to destroy the original value completely. Fixes rdar://147791932.
2025-04-15 13:40:22 -07:00
Anthony Latsis
a84dfc8387 [Gardening] Fix some set but not used variables 2025-01-30 21:34:38 +00:00
Nate Chandler
3589246778 [Test] Underscored fieldsensitive_multidefuse_liverange.
Use underscores rather than hyphens so that text editors understand the
name as a single word.
2024-07-25 13:50:25 -07:00
Tim Kientzle
1098054291 Merge branch 'main' into tbkka-assertions2 2024-06-18 17:52:00 -07:00
Nate Chandler
e2fcdb4524 [MoveOnlyAddressChecker] Handle init_exi_addr.
It's a pass-through for FSPL's purposes.

rdar://128900124
2024-06-06 19:04:41 -07:00
Tim Kientzle
1d961ba22d Add #include "swift/Basic/Assertions.h" to a lot of source files
Although I don't plan to bring over new assertions wholesale
into the current qualification branch, it's entirely possible
that various minor changes in main will use the new assertions;
having this basic support in the release branch will simplify that.
(This is why I'm adding the includes as a separate pass from
rewriting the individual assertions)
2024-06-05 19:37:30 -07:00
Nate Chandler
465886e1e4 [MoveOnlyAddressChecker] Handle open_exi_addr.
It's a pass-through for FSPL's purposes.
2024-05-23 12:26:43 -07:00
Joe Groff
82e566a23a SILGen: Treat Optional x! force unwrapping as a forwarding operation.
Like `?` or property access, `x!` can be borrowing, consuming, or mutated
through depending on the use site and the ownership of the base value.
Alter SILGen to emit `x!` as a borrowing operation when the result is only
used as a borrow. Fix the move-only checker not to treat the unreachable
branch as a dead path for values and try to destroy the value unnecessarily
and possibly out-of-order with cleanups on the value. Fixes rdar://127459955.
2024-05-08 15:35:07 -07:00
Nate Chandler
5325a4d5f8 [MoveOnlyAddressChecker] Fix empty struct repr.
An empty struct without a deinit gets a single bit which is used to
track the struct's liveness.  Previously, an empty struct with a deinit
also only got a single bit.  Consequently, when discarding the struct
(i.e. dropping the deinit), there was no bit left to represent the
struct.  This resulted in a failure to track liveness for the value.

rdar://126863003
2024-04-22 08:42:14 -07:00
Nate Chandler
d11d97d210 [FSPL] Use autogen'd loc. 2024-04-19 12:38:11 -07:00
Nate Chandler
d28a12d356 [MoveOnlyAddressChecker] Handle enum deinits.
Previously, the enum representation was fixed to represent the different
cases payloads separately with the unchecked_take_enum_data_addr
instruction consuming all fields but that whose address is obtained.
In a few places, handling for enum deinits was left undone with an
assertion that the enum not have one.

Here, the deinit bit of the enum is shifted to the end.  And the
assertions are replaced with handling.  Finally, the logic for inserting
destroys after switch_enum_addr instructions is fixed.
2024-04-19 12:37:34 -07:00
Nate Chandler
a0a1ff2a04 [MoveOnlyAddressChecker] Fix enum repr.
Change FieldSensitive's enum representation to allow distinguishing
among the elements with associated value.  Consider
`unchecked_take_enum_data_addr` to consume all other fields than that
taken.

rdar://125113258
2024-03-21 10:48:32 -07:00
Nate Chandler
4f6f8d9459 [NFC] MoveOnly: Map operand to list of ranges. 2024-03-20 12:52:57 -07:00
Nate Chandler
76348df0cf [MoveOnlyAddressChecker] Fix repr for consumes.
An instruction can consume multiple (discontiguous) fields.  Use a
SmallBitVector to track the fields consumed by an instruction rather
than a TypeTreeLeafRange.

rdar://125103951
2024-03-20 12:08:48 -07:00
Nate Chandler
7feb7e2675 [NFC] FSPrunedLiveness: Move impl to cpp file.
The function is long and will get longer.
2024-03-20 08:20:16 -07:00
Joe Groff
1166f2e0d8 FieldSensitivePrunedLiveness: Handle conditionality of try_apply defs.
A `try_apply` with indirect out arguments is only a def for those arguments on
the success path. Model this by sinking the def-ness of the instruction into the
success branch of the try_apply, and introducing a new `DeadToLiveEdge` mode for
block liveness which stops propagation of use-before-def conditions into the
block that introduced the def. Fixes rdar://118567869.
2024-03-19 22:46:26 -07:00
Nate Chandler
6100a1b495 Allow partial consumption of self in deinit.
Basic support for partial consumption in deinit without full support for
all future uses of drop_deinit.
2024-02-28 15:57:09 -08:00
Ben Barham
ef8825bfe6 Migrate llvm::Optional to std::optional
LLVM has removed llvm::Optional, move over to std::optional. Also
clang-format to fix up all the renamed #includes.
2024-02-21 11:20:06 -08:00
Joe Groff
01405ba2e8 Fixes for compound payloads in borrowing switches.
Fill in a missing path for destructuring loadable elements from
address-only tuples in a borrowing context. Enclose projections in their
own separate accesses so that they are analyzed independently by the
move checker.
2024-02-19 17:37:34 -08:00
Joe Groff
0365c6abba MoveOnlyAddressUtils: Fixes for borrowing switch over address-only types.
Relax some existing pattern matches and add some unhandled instructions to the
walkers so that borrowing switches over address-only enums are properly analyzed
for incorrect consumption. Add a `[strict]` flag to `mark_unresolved_move_only_value`
to indicate a borrow access that should remain a borrow access even if the subject
is later stack-promoted from a box.
2024-02-12 20:20:50 -08:00
Joe Groff
03e2e8f476 BorrowToDestructureUtils: handle borrowing switches.
Instead of trying to convert all switches into consumes, allow a switch of a borrow
to remain as such.
2024-01-31 20:38:22 -08:00
Nate Chandler
9ca6b9ac1f [Test] Print to stdout.
In the C++ sources it is slightly more convenient to dump to stderr than
to print to stdout, but it is rather more unsightly to print to stderr
from the Swift sources.  Switch to stdout.  Also allows the dump
functions to be marked debug only.
2023-10-10 08:19:44 -07:00
Nate Chandler
05bec97203 [FSPrunedLiveness] Add extendToNonUse.
And use it in lifetime maximization.

The preexisting member function updateForUse has been updated to match
PrunedLiveness and gravitate towards lifetimeEnding=false.

For a fixed instruction and bit, if called with lifetimeEnding=true and
then lifetimeEnding=false, the lifetime-ending-ness of the instruction
at the bit will be false; and if it is again called with
lifetimeEnding=true, the lifetime-ending-ness of the instruction at the
bit will remain false.

In contrast the new member function extendToUse does not alter the
lifetime-ending-ness if it is already set.  If it is unset, the function
sets the bit to lifetimeEnding=false.
2023-09-26 11:45:23 -07:00
Michael Gottesman
c3d2276241 [silgen] Eliminate two more cases around subscripts where we were not borrowing.
Also, the store_borrow work in the previous patch caused some additional issues
to crop up. I fixed them in this PR and added some tests in the process.
2023-08-02 11:09:31 -07:00
Michael Gottesman
823f008c99 Merge pull request #67145 from gottesmm/pr-694caf05ac09f8c08fb766c7589fe060c927f528
[move-only] Ban partial reinitialization after consuming a value.
2023-07-06 05:24:12 -07:00
Michael Gottesman
69a03c93f9 [move-only] Ban partial reinitialization after consuming a value.
This is similar to our ban on partial consuming a value for this release. The
reason for this is that, one can achieve a similar affect as partial consumption
via a consumption of the entire value and then a partial reinitialization. Example:

```swift
struct X : ~Copyable { var i = 5, var i2 = Klass() }
var x = X()
_ = consume x
x.i = 5
```

in the case above, we now have a value that is in a partially initialized state.

We still allow for move only types to have their fields initialized as long as
there is an intervening init.

rdar://111498740
2023-07-05 20:26:26 -07:00
Nate Chandler
22df319549 [Test] Ensourced fieldsensitive-multidefuse...
-liverange.  Moved the test next to the code it calls.
2023-07-04 11:52:14 -07:00
Nate Chandler
0b30bd7361 [FieldSensitivePL] NFC: Added initDef(bit vector).
The new overload iterates over the contiguous ranges in the bit vector
and calls through to the overload that takes a range.
2023-06-27 12:10: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
92fd8da3c3 [FieldSensitivePL] Fixed use-before-def handling.
rdar://111118843
2023-06-23 10:16:53 -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
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
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
Nate Chandler
d067453ee1 [FieldSensitivePL] NFC: Implemented print.
The members were declared but undefined.
2023-06-16 14:50:18 -07:00
Michael Gottesman
43f42e2c04 [borrowing/consuming] Add new instruction: moveonlywrapper_to_copyable_addr.
The reason why I am using a different instruction for addresses and objects here
is that the object checker doesnt have to deal with things like initialization.
2023-06-06 12:42:23 -04:00
Michael Gottesman
5bef851dfa [move-only] Fix a thinko in FieldSensitivePrunedLiveBlocks::updateForUse.
I think this was a mistake from when I changed implementations to use pure
scalar bit processing rather than processing all at once. Instead of just
updating the internal found resulting uses array, we were appending to it.

Some notes:

1. This actually did not break anything semantically in the move checker since
we do not use this array in the caller in anyway. We just use it internally in
the routine to first lookup the current state which we then process in the
routine. That being said, this API is written such that a user /could/ do that
and we want to allow for users to be able to do that so that we match what
PrunedLiveness does.

2. This could cause memory corruption due to iterator invalidation if by
appending we caused the SmallVector to reallocate as we iterated over the
array.

So to fix this I did the following:

a. I changed the push_back to be an assignment.
b. I removed llvm::enumerate just out of paranoia if the assignment could
   potentially cause iterator invalidation.

The given test exercises this code path and with the old behavior would crash
with asan or guard malloc.

rdar://109673338
2023-05-22 15:02:00 -07:00
Michael Gottesman
94fb5ce2f9 [move-only] Treat empty structs as if they have a single element.
rdar://104395115
2023-04-12 20:56:31 -07:00
Michael Gottesman
d1b206b994 [move-only] Move FieldSensitivePrunedLiveness logging behind an option flag
Sometimes it is useful to have this information when debugging the move checker,
but often times it spews so much output that it is not useful.
2023-03-08 12:18:09 -08:00
Michael Gottesman
d5aea69335 [sil] Refactor field sensitive pruned liveness so it can be used with different sized root values. 2023-02-07 16:27:28 -08:00
Michael Gottesman
3b72951148 [sil] Provide FieldSensitivePrunedLiveness with its own implementation of PrunedLiveBlocks called FieldSensitivePrunedLiveBlocks.
This will let the non-field sensitive version use a more performant
implementation internally. This is important since PrunedLiveBlocks is used in
the hot path when working with Ownership SSA, while the field sensitive version
is only used for certain diagnostics.

NOTE: I did not refactor PrunedLiveness to use the faster implementation... this
is just a quick pass over the code to prepare for that change.
2023-02-07 16:26:41 -08:00
Michael Gottesman
89176928ee Merge pull request #63213 from gottesmm/rdar103271138
[move-only] Implement borrow+struct_extract to restructure transform
2023-01-26 07:19:10 -08:00
Michael Gottesman
885eb21d37 [noimplicitcopy] Changes to borrow+gep -> destructure transform to support noimplicitcopy. 2023-01-25 14:55:52 -08:00
Erik Eckstein
7d8bf37e5e change to the new llvm::Optional APIs
This is a follow-up of https://github.com/apple/swift/pull/62217
2023-01-25 09:18:36 +01:00
Michael Gottesman
4ad2bc93ba [field-sensitive-pruned-liveness] Some small changes.
Specifically:

1. I added to the documentation at the top of the file that our representation
allows for partial init/reinit of structs/tuples from parts.

2. I renamed SubElementNumber to SubElementOffset. This I think fits the actual
use case better and makes it clearer what one is working with (the offset inside
a type of a subelement of the type).

3. I added some small helpers to TypeSubElementCount and SubElementOffset for
adding/subtracting from them.

4. I added the ability to iterate over just consuming/nonconsuming users in
FieldSensitivePrunedLiveness. Just a useful little helper.
2023-01-24 15:28:12 -08:00