Commit Graph

75 Commits

Author SHA1 Message Date
Meghana Gupta
d9a2ff4ff2 Update lifetime completion utility to consider return_borrow
When return_borrow has both lifetime ending and non-lifetime ending use, consider it lifetime ending.
2025-10-23 05:19:13 -07:00
Nate Chandler
d49e9ea682 [NFC] PrunedLiveness: Factor out areWithinBoundary
For historical reasons, there was an API to check whether operands were
within the boundary which just checked whether those operands' users
were within the buondary.  Make a copy of the method deal in
instructions and factor the original API through it.
2025-08-08 14:53:01 -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
Nate Chandler
4135540f62 [NFC] PrunedLiveness: Permit postDomBlocks dupes.
According to the documentation,

```
It's ok if postDomBlocks has duplicates or extraneous blocks, as long
as they jointly post-dominate all live blocks that aren't on dead-end
paths.
```

Previously, though, duplicates resulted in trapping: each element of
`postDomBlocks` is pushed into a `BasicBlockWorklist`; when the second
occurrence of an element in `postDomBlocks` was encountered,
`BasicBlockWorklist::push` would trigger an assertion failure.

Here, `pushIfNotVisited` is called instead.
2025-01-13 17:00:30 -08:00
Nate Chandler
86cd9603da [PrunedLiveness] Add lower detail boundary.
To enable those clients which care only about _blocks_ whose
instructions or dead-defs make up the liveness boundary to avoid
iterating instruction lists, enhance boundary computation with a second
type (`PrunedLivenessBlockBoundary`) and migrate some methods from
liveness onto the boundary types to enable dispatching on the boundary
type to do only the amount of analysis that's necessary.
2024-08-26 16:04:57 -07:00
Nate Chandler
812891cf81 [NFC] PrunedLiveness: Clarified boundary API.
When checking whether an instruction is contained in a liveness
boundary, a pointer to a DeadEndBlocks instance must always be passed.
When the pointer is null, it is only checked that the instruction occurs
within the direct live region.  When the pointer is non-null, it is
checked whether the instruction occurs within the region obtained by
extending the live region up to the availability boundary within
dead-end regions that are adjacent to the non-lifetime-ending portion of
the liveness boundary.
2024-07-23 13:38:35 -07:00
Nate Chandler
e0da318129 [PrunedLiveness] Fix extended boundary check.
The areUsesWithinBoundary/areUsesOutsideBoundary methods take the
dead-ends because the region that they're checking for containment
within contains more than just (is a (non-strict) superset of) the
pruned live region.  On the other hand, the region also contains _less_
than (is a (non-strict) subset of) the available region.  Instructions
are in this extended region only if they're in a dead-end block which is
forwards reachable from the non-lifetime-ending liveness boundary.
2024-07-22 21:51:34 -07:00
Nate Chandler
99b9059a97 [PrunedLiveness] Branch summary merges to ending.
A branch instruction that is both a lifetime-ending user and also a
non-lifetime-ending of a value should be regarded as a lifetime-ending
user.

Without this, utilities that rely on PrunedLiveness such as
`LinearLiveness` and `InteriorLiveness` both incorrectly report that a
branch featuring a value and also a reborrow or guaranteed phi are
non-ending.

rdar://130427564
2024-06-28 08:49:20 -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
9d7db52bed [NFC] PrunedLiveness: Tweaked enum wrapper.
Clarify methods.  Unfortunately, without other changes I haven't
identified, the `enum class` can't be made an `enum` for ideal usage.
2024-06-05 16:27:45 -07:00
Nate Chandler
9d42d69c0a [PrunedLiveness] Fix boundary check for dead-ends.
Consider dead, dead-end blocks within the availability boundary to be
within the boundary.

rdar://126965232
2024-05-16 15:53:06 -07:00
Nate Chandler
cd14f4cbed [NFC] PrunedLiveness: Factor out duplicated method
In preparation to make it more complex.
2024-05-15 19:23:11 -07: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
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
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
c1716c9dfe [PrunedLiveness] Add extendToNonUse.
And use it in lifetime extension/maximization.

The new member function differs from updateForUse in that it doesn't
overwrite the old value for lifetime ending associated with the
instruction (calling updateForUse with lifetimeEnding=false overwrites
the flag set by a previous call with lifetimeEnding=true because if an
instruction both consumes and doesn't consume a copy-extended value, the
value must be live after the instruction).
2023-09-26 11:45:22 -07:00
Nate Chandler
7856842d07 [Test] Renamed with underscores.
Hyphens are not typically used in identifiers and make it a bit trickier
to search.
2023-09-25 18:49:29 -07:00
Nate Chandler
fcec328c54 [Test] Ensourced multidefuse-liveness.
Moved the test next to the code it calls.
2023-07-04 11:52:13 -07:00
Nate Chandler
f99637156b [Test] Ensourced multidef-liveness.
Moved the test next to the code it calls.
2023-07-04 11:52:13 -07:00
Nate Chandler
ef02dc2081 [Test] Ensourced ssa-liveness.
Moved the test next to the code it calls.
2023-07-04 11:52:13 -07:00
Nate Chandler
3343ab926d [Test] Ensourced pruned-livenes-boundary...
-with-list-of-last-users-insertion-points.  Moved the test next to the
code it calls.
2023-07-04 11:52:13 -07:00
Andrew Trick
c9eb1aea91 MultiDefPrunedLiveness: add support for arbitrary uses/defs.
This now supports liveness holes within blocks where previously we
expected a phi def.

PrunedLiveness is streamlined for SSA liveness where we expect the
defs and uses to be related in the SSA def-use graph.
MultiDefPrunedLiveness was added on top of SSAPrunedLivenes to handle
extended SSA liveness that occurs with phis, but are still connected
in the def-use graph. Recently MultiDefPrunedLiveness was repurposed
for liveness of addressible storage. This means that we can now have
uses before defs in the same block without a corresponding phi.

Fortunately, handling this case is a straightforward extension of
MultiDefPrunedLiveness that does not complicate or penalize the
streamlined SSA case.
2023-04-04 10:22:32 -07:00
Andrew Trick
d44c7f3b99 [NFC] Move the updateForUse API into PrunedliveRange
PrunedLiveness only knows about the live blocks and uses.

The PrunedLiveRange subclass is now responsible for updating liveness
based on both the defs and uses. This is in preparation for handling
non-SSA liveness when uses occur before the first def.
2023-04-04 10:22:32 -07:00
Andrew Trick
927d526ac9 silence a noasserts warning 2023-04-04 10:22:32 -07:00
Andrew Trick
0c8ecb54bf Revert "MultiDefPrunedLiveness: add support for arbitrary uses/defs." 2023-03-28 17:43:42 -07:00
Andrew Trick
6b77b79ac8 MultiDefPrunedLiveness: add support for arbitrary uses/defs.
This now supports liveness holes within blocks where previously we
expected a phi def.

PrunedLiveness is streamlined for SSA liveness where we expect the
defs and uses to be related in the SSA def-use graph.
MultiDefPrunedLiveness was added on top of SSAPrunedLivenes to handle
extended SSA liveness that occurs with phis, but are still connected
in the def-use graph. Recently MultiDefPrunedLiveness was repurposed
for liveness of addressible storage. This means that we can now have
uses before defs in the same block without a corresponding phi.

Fortunately, handling this case is a straightforward extension of
MultiDefPrunedLiveness that does not complicate or penalize the
streamlined SSA case.
2023-03-24 18:40:31 -07:00
Andrew Trick
44fc97d340 [NFC] Move the updateForUse API into PrunedliveRange
PrunedLiveness only knows about the live blocks and uses.

The PrunedLiveRange subclass is now responsible for updating liveness
based on both the defs and uses. This is in preparation for handling
non-SSA liveness when uses occur before the first def.
2023-03-23 22:05:54 -07:00
Andrew Trick
f30fd127fa silence a noasserts warning 2023-03-23 16:08:36 -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
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
Andrew Trick
4224d940ec Add visitInnerAdjacentPhis OSSA helper
This API is the inverse of visitEnclosingDefs when called on a phi.

This replaces the visitAdjacentReborrowsOfPhi algorithm with a small
loop that simply checks all the phis in the current block.

This should all be fairly efficient once SILArgument has a "reborrow"
flag.
2023-02-06 23:11:23 -08:00
Andrew Trick
7990dda02b Cleanup PrunedLiveness interface.
In preparation for adding OwnershipLiveness.

Rename Simple LiveRangeSummary to LiveRangeSummary.

Add initializeDefNode helpers to avoid confusion about the argument
type.

Add defBegin/defEnd iterators in MultiDefPrunedLiveness.
2023-01-24 23:26:40 -08:00
Andrew Trick
7dc9405131 Add a visited set for PrunedLiveness guaranteed value. 2023-01-13 14:16:15 -08:00
Andrew Trick
599b1d1ae4 Handle guaranteed phis conservatively in a few more places. 2023-01-13 08:55:16 -08:00
swift-ci
c547f57b06 Merge pull request #62737 from valeriyvan/PrunedLiveness-null-derefence
Fix NULL pointer dereference
2023-01-12 03:53:22 -08:00
Andrew Trick
208bb76ce3 Fix MultiDefPrunedLiveness; add boundaries for dead end blocks.
Make sure liveness reports a complete boundary even for OSSA lifetimes
that are incomplete. Definition blocks can be on the liveness boundary
in this case.
2023-01-09 23:01:37 -08:00
Andrew Trick
07d4655fb7 Fix an assert in MultiDefPrunedLiveness
Fixes an assert that was meant for a narrow case and accidentally
applied too broadly.

This variation of the liveness utilities wasn't being exercised widely,
and is difficult to test with valid OSSA.
2023-01-09 13:46:58 -08:00
Michael Gottesman
5dceb82a76 [pruned-liveness] Change computeScalarUseBlockLiveness to internally sue the scalar version of markBlockLive 2023-01-07 14:40:04 -08:00
Michael Gottesman
82abf02883 [pruned-liveness] Change the internal machinery of updateForUse to use only scalar logic.
I did this by doing the following:

1. I renamed computeUseBlockLiveness to computeScalarUseBlockLiveness and
changed it to take a specific bit that it is testing for.

2. I changed the logic that already existed in this code path that worked scalar
by scalar to use scalar logic rather than call the broken multi-bit at a time
code path.

3. We took advantage of resultingFoundLiveness now only returning the requested
bits instead of all bits. This ensures that we do not run
computeScalarUseBlockLiveness for those unneeded dead bits resulting in liveness
being inappropriately propagated into predecessors.
2023-01-07 14:28:41 -08:00
Michael Gottesman
72c72968e8 [pruned-liveness] Make it so that PrunedLiveBlocks prints out all bits except just the first bit. 2023-01-07 14:14:59 -08:00
Valeriy Van
ad33e6a7f7 Fix NULL pointer dereference 2022-12-21 22:58:00 +02:00
Meghana Gupta
511739b494 Delete OperandOwnership::GuaranteedForwardingPhi
Use OperandOwnership::GuaranteedForwarding instead.
2022-12-13 12:51:31 -08:00
Michael Gottesman
3f90afb901 [move-addr] Move Field Sensitive Pruned Liveness into its own header/cpp impl. 2022-12-08 10:29:48 -08:00
Meghana Gupta
786eb94853 Support @guaranteed forwarding phis 2022-10-19 19:54:27 -07:00
Meghana Gupta
b1f719709b Rename ForwardingBorrow -> GuaranteedForwarding 2022-10-19 19:54:27 -07:00
Nate Chandler
c2f354eefd [PrunedLiveness] Addressed boundary TODO.
With guaranteed phis, we'll be able to encounter cases where the last
users are BranchInsts which use but don't consume a value.  But even
without them, we can still test the API.
2022-10-17 16:50:04 -07:00
Andrew Trick
6af0b6d818 Use ScopedAddressValue in PrunedLiveness
to handle scoped addresses properly
2022-10-12 12:32:15 -07:00