Commit Graph

36 Commits

Author SHA1 Message Date
Nate Chandler
f201ceebe1 [NFC] MoveOnly: Add parameter to function.
For now, it is unused.
2025-04-23 13:28:49 -07:00
Nate Chandler
b3d9e0a5aa [NFC] MoveOnly: Delete some dead code.
Before adding a new parameter to the function being called.
2025-04-23 13:28:49 -07:00
Andrew Trick
d9dd93560d Support mark_dependence_addr in SIL passes. 2025-03-25 23:02:45 -07:00
Andrew Trick
f1792d80b3 Fix BorrowingOperand.visitScopeEndingUses
Only return false if the visitor returns false. Clients were ignoring the
result.

If the BorrowingOperand does not create a borrow scope, call visitUnknownUse
instead.

Until we have complete lifetimes, to avoid breaking code that cannot handle dead
defs, consider a dead borrow scope to be an unknown use.
2025-02-25 23:08:54 -08:00
Andrew Trick
e705a6d7c3 Temporarily introduce AnyInteriorPointer operand ownership.
This is necessary to fix a recent OSSA bug that breaks common occurrences on
mark_dependence [nonescaping]. Rather than reverting that change above, we make
forward progress toward implicit borrows scopes, as was the original intention.

In the near future, all InteriorPointer instructions will create an implicit
borrow scope. This means we have the option of not emitting extraneous
begin/end_borrow instructions around intructions like ref_element_addr,
open_existential, and project_box. After that, we can also migrate
GuaranteedForwarding instructions like tuple_extract and struct_extract.
2025-02-05 16:23:02 -08:00
Joe Groff
1e37b67a96 BorrowToDestructureTransform: Fix order of operations when placing borrows around InteriorPointerOperands.
The code here determined the borrow scope of an InteriorPointerOperand use of a borrow using
`visitBaseValueScopeEndingUses`, but it does so after rewriting the operand, so the base
value would sometimes be incorrect leading to missing `end_borrows` in the rewritten code.
Fixes rdar://133333278.
2025-02-04 18:43:40 -08:00
Andrew Trick
508e6760ec [MoveObjectChecker] handle mark_depends
MoveOnlyBorrowsToDestructure: fix gatherBorrows to ignore mark_dependence base
operand uses.
2024-10-22 09:27:02 -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
Joe Groff
5ad260315b Use the BorrowingSwitch implementation for all noncopyable switches.
It works well enough now that it should be an acceptable replacement for both
borrowing and consuming switches that works in more correct situations than the
previous implementation. This does however expose a few known issues that I'll
try to fix in follow ups:

- overconsumes cause verifier errors instead of raising diagnostics (rdar://125381446)
- cases with multiple pattern labels aren't yet supported (rdar://125188955)
- copyable types with the `borrowing` or `consuming` modifiers should probably use
  noncopyable pattern matching.

The `BorrowingSwitch` flag is still necessary to enable the surface-level syntax
changes (switches without `consume` and the `_borrowing` modifier, for instance).
2024-04-09 16:31:01 -07:00
Meghana Gupta
50b358c64f Merge pull request #72359 from meg-gupta/skiphismdi
Fix utilities that may see phis of mark_dependence [nonescaping]
2024-03-21 18:28:08 -07:00
Meghana Gupta
3ebef80261 Fix utilities that may see phis of mark_dependence [nonescaping] 2024-03-20 15:44:11 -07:00
Nate Chandler
4f6f8d9459 [NFC] MoveOnly: Map operand to list of ranges. 2024-03-20 12:52:57 -07:00
Nate Chandler
b6e8ecaa9f [NFC] MoveOnly: Used newly standard constructor. 2024-03-20 12:35:14 -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
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
Joe Groff
161183cbc4 Merge pull request #71803 from jckarter/begin-borrow-fixed-switch-subject
SIL: Enclose switch subjects in a new begin_borrow [fixed] variant.
2024-02-22 14:45:17 -08:00
Joe Groff
d75a62ce64 SIL: Enclose switch subjects in a new begin_borrow [fixed] variant.
We want to preserve the borrow scope during switch dispatch so that move-only
checking doesn't try to analyze destructures or consumes out of it. SILGen
should mark anywhere that's a potential possibility with its own marker so that
it gets borrow checked independently.
2024-02-21 20:41:20 -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
Allan Shortlidge
b6d41046de NFC: Address a couple of unused variable warnings. 2024-02-01 18:15:42 -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
Joe Groff
1dcf271fe0 SIL: Treat store_borrow as borrowing its source, and have the move-only checker account for borrow scopes.
When rewriting uses of a noncopyable value, the move-only checker failed to take into account
the scope of borrowing uses when establishing the final lifetimes of values. One way this
manifested was when borrowed values get reabstracted from value to in-memory representations,
using a store_borrow instruction, the lifetime of the original borrow would be ended immediately
after the store_borrow begins rather than after the matching end_borrow. Fix this by, first,
changing `store_borrow` to be treated as a borrowing use of its source rather than an
interior-pointer use; this should be more accurate overall since `store_borrow` borrows the
entire source value for a well-scoped duration balanced by `end_borrow` instructions. That done,
change MoveOnlyBorrowToDestructureUtils so that when it sees a borrow use, it ends the borrow
at the end(s) of the use's borrow scope, instead of immediately after the beginning of the use.
2023-10-16 09:12:25 -07:00
Michael Gottesman
37d60a08bb [move-only] Rename mark_must_check -> mark_unresolved_non_copyable_value.
I was originally hoping to reuse mark_must_check for multiple types of checkers.
In practice, this is not what happened... so giving it a name specifically to do
with non copyable types makes more sense and makes the code clearer.

Just a pure rename.
2023-08-30 22:29:30 -07:00
Michael Gottesman
9b59588fc3 [move-only] If we have a guaranteed forwarding instruction with only trivial results, treat it as a liveness use.
The reason why we want to do this is that if we treat it as a true forwarding
use, we will visit the uses of the trivial value and treat those as liveness
uses. Since the trivial value is not tied to the lifetime of the underlying
noncopyable value, this can be outside of the lifetime of said value causing a
memory lifetime error. By just treating the guaranteed forwarding instruction
with all trivial values as a liveness use, we avoid this problem.

I added a SIL test, a Swift test, and an Interpreter test that validates this
behavior.

rdar://111497657
2023-06-29 00:00:05 -07:00
Erik Eckstein
6b1697eb06 use new llvm::Optional APIs to fix deprecation warnings 2023-06-28 14:28:38 +02: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
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
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
Michael Gottesman
76e93828ef [move-only] Make it an error if we attempt to destructure/partially invalidate through a field with a deinit.
If one has a type with a deinit, if one were to partially invalidate the value,
the checker will clean up the remaining parts of the value but not the actual
underlying value. This then would cause the deinit of the actual type to be
called.

rdar://101651138
2023-04-12 15:18:56 -07:00
Michael Gottesman
1957f57a92 [move-only] Handle terminator users like yield when converting borrow -> destructure.
rdar://106164128
2023-03-28 16:01:01 -07:00
Andrew Trick
cbe856e53a Cleanup PrunedLiveBlocks
Use BasicBlockBitfield to record per-block liveness state. This has
been the intention since BasicBlockBitfield was first introduced.

Remove the per-field bitfield from PrunedLiveBlocks. This
(re)specializes the data structure for scalar liveness and drastically
simplifies the implementation.

This utility is fundamental to all ownership utilities. It will be on
the critical path in many areas of the compiler, including at
-Onone. It needs to be minimal and as easy as possible for compiler
engineers to understand, investigate, and debug.

This is in preparation for fixing bugs related to multi-def liveness
as used by the move checker.
2023-03-22 02:36:57 -07:00
Andrew Trick
ae64ff5cb0 Rename PrunedLiveness.clear() to invalidate()
Because SILBitfield cannot be cleared.
2023-03-22 01:36:48 -07:00
Andrew Trick
15796e3ff9 PrunedLiveness: add a SILFunction argument
So that liveness can migrate to using a SILBitfield.
2023-03-22 01:36:48 -07:00
Michael Gottesman
50af8fd493 [move-only] Box owned arguments like let parameters. 2023-02-20 11:04:21 -08:00
Michael Gottesman
a571357cce [move-only] Change noncopyable lets to be emitted as boxes like vars.
Some notes:

1. This ensures that if we capture them, we just capture the box by reference.

2. We are still using the old incorrect semantics for captures. I am doing this
   so I can bring this up in separate easy to understand patches all of which
   pass all of the moveonly tests.

3. Most of the test edits are due to small differences in error messages in
   between the object and address checker.

4. I had to add a little support to the move only address checker for a small
   pattern that doesn't occur with vars but do es occur for lets when we codegen
   like this, specifically around enums. The pattern is we perform a load_borrow
   and then copy_value and then use the result of the copy_value. Rather than fight
   SILGen pattern I introduced a small canonicalization into the address checker which
   transforms that pattern into a load [copy] + begin_borrow to restore the codegen
   to a pattern the checker expects.

5. I left noimplicitcopy alone for now. But we should come back around and fix
   it in a similar way. I just did not have time to do so.
2023-02-20 11:04:21 -08:00
Michael Gottesman
6c922af8aa [move-only] Combine the address/object checker in the same pass so that we only run cleanups once.
Otherwise, sometimes when the object checker emits a diagnostic and cleans up
the IR, some of the cleaned up copies are copies that should have been handled
by the address checker. The end result is that the address checker does not emit
diagnostics for that IR. I found this problem was exascerbated when writing code
for escaping closures.

This commit also cleans up the passes in preparation for at a future time moving
some of the transformations into the utils folder.
2023-02-19 13:55:22 -08:00