Commit Graph

206 Commits

Author SHA1 Message Date
Andrew Trick 09c5e7912d Fix Builtin.Borrow<T> OSSA representation
Builtin.Borrow<T> does not introduce a new borrow scope at the level of
SILValue. A SILValue that introduces a borrow scope is expected to be tracked by
OSSA--it cannot produce a trivial value. That borrow scope is expected to have a
scope-ending operation on all paths.

It's not clear how OSSA utilities and passes will handle the previous
implementation which doesn't honor those invariants. Fixing this is needed to
rely on Builtin.Borrow<T> more extensively.

Instead, treat the make_borrow instruction like an instantenous use. It produces
a Builtin.Borrow<T> value with ownership None. That value is completely ignored
by OSSA and does not contribute to liveness of the incoming value.

This is at least a coherent representation, but still incredibly dangerous. The
validity of SIL depends on the programmer using Builtin.makeBorrow
correctly. Add a TODO for implementing verification.

Fixes rdar://173800290 (Fix Builtin.Borrow<T> OSSA representation)
2026-04-01 23:39:55 -07:00
Andrew Trick 2120c0502a Another fix for the OSSA RAUW utility for unowned phis
Fixes rdar://169556118 (Assertion: (succ->getSinglePredecessorBlock() == predBB)
function visitInsertionPoints at ValueLifetime.cpp:37.)
2026-02-05 15:01:11 -08:00
Joe Groff 0f3ddfbcc8 Merge pull request #86545 from jckarter/builtin-borrow
`Builtin.Borrow` implementation
2026-01-26 07:32:31 -08:00
Andrew Trick 96bc9aa90c Fix the OSSA RAUW utility for unowned phis
The OwnershipRAUW utility is called by CSE, SILCombine, etc. whenever OSSA
values are substituted or combined. It handles ownership corner cases by
creating new copies. Destroys need to be insert for those new copies after all
original uses. It is impossible to do that when phis are involved. The utility
already checks for phis involving owned or guaranteed values, but unowned phis
were not anticipated.

Fixes rdar://168620481 swift-frontend crash: While running pass
SILFunctionTransform "GenericSpecializer"
2026-01-23 21:56:30 -08:00
Joe Groff bc53d4ecb4 SIL: Handle Borrow instructions in more utility visitors. 2026-01-23 08:02:09 -08:00
Joe Groff 373211a902 SILGen: Lowering for Builtin.makeBorrow 2026-01-23 08:02:08 -08:00
Meghana Gupta 76b3374e81 Merge pull request #86155 from meg-gupta/removeborrowoptbailouts
Enable GenericSpecializer for borrow/mutate accessors and fix it for conditionally copyable types
2026-01-02 04:26:05 -08:00
Erik Eckstein 15636a197c SIL: Fix the ownership verifier for guaranteed phi arguments
The verifier reported a false error in case an unowned (trivial) value was used in an guaranteed phi argument outside the liverange of a borrow scope.
For example:

```
  %2 = begin_borrow %0
  %3 = struct_extract %2 , #KlassAndInt.int                // %3 is trivial and can outlive the borrow scope
  end_borrow %2
  %6 = struct $KlassAndInt (%someOtherGuaranteedValue, %3)
  br bb2(%6)

bb2(%8 : @guaranteed $KlassAndInt):      // false error reported at the uses of %8
```
2025-12-22 07:54:39 +01:00
Meghana Gupta 7bdd713bd0 Bailout of getAllBorrowIntroducingValues for ScopedAddressValue introducers 2025-12-16 13:39:34 -08:00
John McCall 7a6ee1134c [NFC] Add a utility function for testing for a specific BuiltinInst 2025-11-03 13:44:18 -08:00
Nate Chandler cbe383524c [NFC] OwnershipUtils: Add a UsePoint type.
The type is a union of an Operand (a real use) and a SILInstruction (an
implicit use).  Such a type is needed to reflect the fact that with
incomplete lifetimes, values can be implicitly destroyed at the
terminators of blocks in dead end regions (along the vaule's
availability boundary).
2025-08-08 15:08:20 -07:00
Nate Chandler 99091c93ae [NFC] OwnershipUtils: Factored out function.
For historical reasons, the existing function
(`areUsesWithinExtendedScope`) trafficked in operands rather than
instructions.  Now that PrunedLiveness has an API that deals with
instructions, add a function (`areWithinExtendedScope`) which does as
well.  Factor the existing function through this new function.
2025-08-08 14:59:36 -07:00
Andrew Trick edcaecc09d Fix BorrowedValue::visitInteriorPointerOperandHelper
to handle borrowed-from (as a ForwardingInstruction).
2025-02-25 23:08:55 -08:00
Andrew Trick 5f8b93c66a Fix interior liveness to report the escaping instruction as a use. 2025-02-25 23:08:55 -08:00
Andrew Trick f29bb44d07 OwnershipUseVisitor::visitInnerBorrowUses: support dependent values
Add liveness support for dependent values: borrowed-from & mark_dependence so
they aren't reported as unknown uses.

Centralize the logic in BorrowingOperand::getScopeIntroducingUserResult
and BorrowingOperand::getDependentUserResult().
2025-02-25 23:08:55 -08:00
Andrew Trick 1cb4d50877 Fix BorrowingOperand::visitScopeEndingUses() invariants.
This API only makes sense for a scoped borrow-introducer such as:
- reborrow
- owned mark_dependence

Borrowing operands that forward guaranteed values do not have scope-ending uses.
2025-02-25 23:08:54 -08:00
Andrew Trick e78aa38204 Remove BorrowingOperand.getImplicitUses.
It is buggy/misleading because of dead-def handling. The current operand may be
re-pushed if it is a dead borrow scope.
2025-02-25 23:08:54 -08:00
Andrew Trick b3a445fb55 Fix BorrowingOperand::getBorrowIntroducingUserResult()
To handle borrowing operands that produce a dependence value but do not create a
nested borrow scope. This includes non-reborrow borrowed-from and guaranteed
mark_dependence [nonescaping].
2025-02-25 23:08:54 -08: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 01c3343b05 Fix mark_dependence ownership: compatibility with owned values
This fixes an OSSA verification bug introduced here:

    commit 79b649854b
    Author: Meghana Gupta <meghanavgupta@gmail.com>
    Date:   Wed Jan 22 01:24:49 2025

        Fix operand ownership of mark_dependence [nonescaping] of address values

The bug only showed up with mark_dependence [nonescaping], which means mainly
affects `~Escapable` types. Adddressors happened to work because SILGen was
emitting a borrow scope around them.

Rather than reverting the change above, this fix migrates mark_dependence
[nonescaping] to an implicit borrow scope.

Fixes rdar://144199759 (Assert: mark_dependence [nonescaping]:
ownership incompatible with an owned value)
2025-02-05 16:23:14 -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
Meghana Gupta 6f375aa6b6 Look through forwarding instructions while querying ownership root
Fixes rdar://142507746
2025-01-10 11:52:06 -08:00
Meghana Gupta 4cab04e190 Fix reborrow verifier to look through borrowed from 2024-12-16 10:23:18 -08:00
Andrew Trick 4612728581 [NFC] Add BeginApplyInst::getEndApplyUses() API.
A begin_apply token may be used by operands that do not end the coroutine:
mark_dependence.

We need an API that gives us only the coroutine-ending uses. This blocks
~Escapable accessors.

end_borrow is considered coroutine-ending even though it does not actually
terminate the coroutine.

We cannot simply ask isLifetimeEnding, because end_apply and abort_apply do not
end any lifetime.
2024-11-18 01:37:00 -08:00
Erik Eckstein 7bf0010c92 SIL: remove computeIsReborrow
This API computes the re-borrow flags for guaranteed phis based on the presence of forwarding instructions in the incoming values.
This is not correct in all cases, because optimizations can optimize away forwarding instructions.

Fixes a verifier crash: rdar://139280579
2024-11-12 09:26:59 +01:00
Erik Eckstein 83224b255e SIL: automatically set the reborrow flags for phi-arguments when creating an end_borrow or setting the operand of an end_borrow
This is done for all transitively incoming phi-arguments of an end_borrow operand.
2024-11-12 09:26:58 +01:00
Nate Chandler 5a93b7d7d5 [Test] Underscored visit_inner_adjacent_phis.
Use underscores rather than hyphens so that text editors understand the
name as a single word.
2024-07-25 13:50:18 -07:00
Nate Chandler 1fbc526bc8 [Test] Underscored find_borrow_introducers.
Use underscores rather than hyphens so that text editors understand the
name as a single word.
2024-07-25 13:50:18 -07:00
Nate Chandler a3922144f6 [Test] Underscored find_enclosing_defs.
Use underscores rather than hyphens so that text editors understand the
name as a single word.
2024-07-25 13:50:18 -07:00
Nate Chandler 7119b9e713 [Test] Underscored has_pointer_escape.
Use underscores rather than hyphens so that text editors understand the
name as a single word.
2024-07-25 13:50:18 -07:00
Tim Kientzle 1098054291 Merge branch 'main' into tbkka-assertions2 2024-06-18 17:52:00 -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 81fa65772f [OwnershipLiveness] End at extend_lifetime.
When visiting consumes, also visit `extend_lifetime` instructions.
These instructions are not lifetime ending, but together with the
consumes, they enclose the users of a value.

Add a flag to LinearLiveness to control whether these instructions are
added so that the verifier can use verify that all such instructions
appear outside the linear lifetime boundary (not including them).
2024-06-05 16:28:28 -07:00
Nate Chandler 29d046fa42 [SIL] Add BorrowedValueKind::BeginApplyToken.
The token is a guaranteed value introduced by the begin_apply and
consumed by its end_apply, abort_apply, and end_borrow users.
2024-04-25 17:03:43 -07:00
Erik Eckstein 96cf03fe95 OwnershipUtils: fix a warning
Removed a left over from the work on the borrowed-from instruction
2024-04-15 12:18:05 +02:00
Erik Eckstein e14c1d1f62 SIL, Optimizer: update and handle borrowed-from instructions
Compute, update and handle borrowed-from instruction in various utilities and passes.
Also, used borrowed-from to simplify `gatherBorrowIntroducers` and `gatherEnclosingValues`.
Replace those utilities by `Value.getBorrowIntroducers` and `Value.getEnclosingValues`, which return a lazily computed Sequence of borrowed/enclosing values.
2024-04-10 13:38:10 +02:00
Erik Eckstein ac4bc89c9a SIL: add the borrowed-from instruction.
It declares from which enclosing values a guaranteed phi argument is borrowed from.
2024-04-10 13:38:10 +02:00
Andrew Trick d7b9149ee5 Fix visitNonEscapingLifetimeEnds to handle mark_dependence uses
Now it visits unknown uses separately rather than asserting.
2024-03-22 14:29:57 -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 9f6c30919b [NFC] SIL: Typed begin_borrow's isLexical. 2024-03-08 22:27:50 -08:00
Andrew Trick 37171e698a Handle mark_dependence [nonescaping] like a borrowing instruction. 2024-01-22 23:57:03 -08:00
Evan Wilde 312bd47f4c Merge remote-tracking branch 'main' into 'rebranch' 2023-10-16 23:00:12 -07:00
Joe Groff 25061fb281 Merge pull request #69169 from jckarter/store-borrow-lifetime-nesting
SIL: Treat store_borrow as borrowing its source, and have the move-only checker account for borrow scopes.
2023-10-16 13:51:40 -07: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
swift-ci 56f70e947a Merge remote-tracking branch 'origin/main' into rebranch 2023-10-10 11:53:54 -07: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
Evan Wilde 309aed4925 Add SmallSetVector replacement
llvm::SmallSetVector changed semantics
(https://reviews.llvm.org/D152497) resulting in build failures in Swift.
The old semantics allowed usage of types that did not have an
`operator==` because `SmallDenseSet` uses `DenseSetInfo<T>::isEqual` to
determine equality. The new implementation switched to using
`std::find`, which internally uses `operator==`. This type is used
pretty frequently with `swift::Type`, which intentionally deletes
`operator==` as it is not the canonical type and therefore cannot be
compared in normal circumstances.

This patch adds a new type-alias to the Swift namespace that provides
the old semantic behavior for `SmallSetVector`. I've also gone through
and replaced usages of `llvm::SmallSetVector` with the
`Swift::SmallSetVector` in places where we're storing a type that
doesn't implement or explicitly deletes `operator==`. The changes to
`llvm::SmallSetVector` should improve compile-time performance, so I
left the `llvm::SmallSetVector` where possible.
2023-07-25 12:28:27 -07:00
Nate Chandler 194904f854 [OwnershipUtils] NFC: Deduplicated implementation.
The only difference between visitLocalScopeEndingUses and
getLocalScopeEndingInstructions is that the former evaluates a lambda
with each `Operand *` and the latter adds `->getUser()` to a
SmallVectorImpl for each.  So factor the latter through the former and
add the users to the SmallVectorImpl in the lambda.
2023-07-11 08:22:59 -07:00
Nate Chandler 9417651d00 [Test] Ensourced find-borrow-introducers.
Moved the test next to the code it calls.
2023-07-04 11:52:13 -07:00
Nate Chandler 8f0378c3bc [Test] Ensourced find-enclosing-defs.
Moved the test next to the code it calls.
2023-07-04 11:52:13 -07:00