Commit Graph

185 Commits

Author SHA1 Message Date
Nate Chandler
b1ccb59f01 [SIL] NFC: Removed visitBorrowIntroUserResults.
It's equivalent to getBorrowIntroducingUserResult except that it's less
convenient to use.  There's only ever one result, so there's no need for
a visitor.  Updated all users to call getBorrowIntroducingUserResult
instead.
2023-04-12 13:41:42 -07:00
Nate Chandler
6a5330b1d7 [SIL] NFC: Duplicated assertions.
Added the assertions from visitBorrowIntroducingUserResults to
getBorrowIntroducingUserResult.  In preparation for deleting the former
in favor of the latter.
2023-04-12 13:41:31 -07:00
Nate Chandler
0fceb33905 [SIL] NFC: Marked function const.
Make it available on const instances.
2023-04-12 13:29:05 -07:00
swift-ci
9807267e02 Merge pull request #64708 from meg-gupta/fixinfinite
Fix infinite loop in the new hasPointerEscape(SILValue) api
2023-03-29 01:27:10 -07:00
Meghana Gupta
84d643fc85 Fix infinite loop in the new hasPointerEscape(SILValue) api 2023-03-28 20:47:27 -07:00
Meghana Gupta
64d344ab07 Support all BorrowedValueKind in hasPointerEscape(BorrowedValue) api 2023-03-28 20:31:27 -07:00
Andrew Trick
119e712c32 Merge pull request #64534 from atrick/liveblocks-bitfield
Cleanup PrunedLiveBlocks
2023-03-22 16:33:08 -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
Nate Chandler
b7f447da6c [NFC] Readability for isRedundantMoveValue.
Improved comments and flattened conditions.
2023-03-21 07:57:43 -07:00
Nate Chandler
6f5114ef68 [OwnershipUtils] Classify more moves as redundant.
Moves from limited use values are redundant.  When a move separates a
non-escaping lifetime from an escaping lifetime, it is still redundant
if the original lifetime couldn't be optimized because it's already as
small as possible.
2023-03-16 18:22:58 -07:00
Nate Chandler
ceb941d1d1 [NFC] Extracted isRedundantMoveValue.
Extracted the predicate from inline in RedundantMoveValueElimination
into the new function which can now be called from elsewhere
(CopyPropagation).
2023-03-15 07:38:59 -07:00
Nate Chandler
af1ac900f9 [SIL] Add hasPointerEscape(SILValue).
There is a preexisting function with this name that takes a
BorrowedValue.  The new function calls that preexisting function if a
BorrowedValue can be constructed from the SILValue.  Otherwise, it looks
for direct uses of the value which qualify as "pointer escapes".
2023-03-10 10:49:53 -08:00
Michael Gottesman
a24d46097f [sil] Teach the various address verifiers about ExplicitCopyAddrInst.
Just treating it the same as copy_addr as expected.
2023-02-17 16:04:47 -08:00
Joe Groff
69e4b95fb8 SIL: Model noescape partial_applys with ownership in OSSA.
Although nonescaping closures are representationally trivial pointers to their
on-stack context, it is useful to model them as borrowing their captures, which
allows for checking correct use of move-only values across the closure, and
lets us model the lifetime dependence between a closure and its captures without
an ad-hoc web of `mark_dependence` instructions.

During ownership elimination, We eliminate copy/destroy_value instructions and
end the partial_apply's lifetime with an explicit dealloc_stack as before,
for compatibility with existing IRGen and non-OSSA aware passes.
2023-02-16 21:43:53 -08:00
Andrew Trick
30f59c7367 Remove an assert from visitForwardedGuaranteedOperands
Some guaranteed forwarding instructions have multiple operands:
mark_dependence, ref_to_bridge_object.

The corresponding instruction types checked here already have
documentation that the forwarded operand is the first operand. The
assert is overly cautious, and checking for indiviudal opcodes would be
tedious maintenance.
2023-02-13 18:04:39 -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
403c37a680 Tweak findTransitiveUsesForAddress implementation
Record uses even when they escape a pointer. This is more consistent
and helps avoids corner cases involving dead address producers.
2023-02-06 11:16:18 -08:00
nate-chandler
2fc7659ed7 Merge pull request #60670 from nate-chandler/lexical_lifetimes/owned_arguments
[SIL] Maintain owned argument lifetimes at inlining.
2023-01-26 18:30:24 -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
Nate Chandler
4422cdcc06 [OwnershipUtils] Match complex nested borrows.
Recognize lexical borrows as nested when their borrowee's guaranteed
reference roots are all lexical borrows.

Addresses the following regressions

Breadcrumbs.MutatedUTF16ToIdx.Mixed         188     882     +369.1%   **0.21x**
Breadcrumbs.MutatedIdxToUTF16.Mixed         230     926     +302.6%   **0.25x**

seen when enabling lexical lifetimes in the standard library.
2023-01-25 11:39:42 -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
Michael Gottesman
e15eab5020 [ownership] Change ForwardingOperand::visitForwardingValues to handle ForwardingOwned terminators that are function exiting correctly.
Previously, we would have just asserted when we passed the operand to
PhiOperand on the next line of the code.
2023-01-24 16:55:54 -08:00
Andrew Trick
599b1d1ae4 Handle guaranteed phis conservatively in a few more places. 2023-01-13 08:55:16 -08:00
Andrew Trick
0a9484597f Add findEnclosingDefs and findBorrowIntroducers utilities.
These APIs are essential for complete OSSA liveness analysis.  The
existing ad-hoc OSSA logic always misses some of the cases handled by
these new utilities. We need to start replacing that ad-hoc logic with
new utilities built on top of these APIs to define away potential
latent bugs.

Add FIXMEs to the inverse API: visitAdjacentBorrowsOfPhi. It should
probably be redesigned in terms of these new APIs.
2023-01-03 09:33:39 -08:00
Andrew Trick
c2ae7e0359 Add visitForwardedGuaranteedOperands utility.
Factors a mess of code in MemAccessUtils to handle forwarding
instruction types into a simpler utility. This utility is also needed
for ownership APIs, which need to be extended to handle these cases.
2023-01-03 09:33:39 -08:00
Meghana Gupta
e2c53dd469 Merge pull request #62570 from meg-gupta/fixossaapi
[OSSA] Minor fixes to swift::findTransitiveUsesForAddress
2022-12-15 10:30:17 -08:00
Meghana Gupta
9360b7bfdb Record debug_value and end_borrow as leaf uses in swift::findTransitiveUsesForAddress
Otherwise the default is AddressUseKind::Unknown
2022-12-13 22:18:14 -08:00
Meghana Gupta
208298ed3e Fix findTransitiveUsesForAddress when foundUses vector is nullptr
The api should not behave differently when foundUses is nullptr.
The only difference should be in populating it.

No tests. Found by code inspection.
2022-12-13 22:18:08 -08:00
Meghana Gupta
511739b494 Delete OperandOwnership::GuaranteedForwardingPhi
Use OperandOwnership::GuaranteedForwarding instead.
2022-12-13 12:51:31 -08:00
Meghana Gupta
b10563909c Update isGuaranteedForwarding api and delete isGuaranteedForwardingPhi api 2022-12-13 12:51:25 -08:00
Andrew Trick
f9861ec9c0 Add APIs for terminator results that forward ownership.
Add TermInst::forwardedOperand.

Add SILArgument::forwardedTerminatorResultOperand. This API will be
moved into a proper TerminatorResult abstraction.

Remove getSingleTerminatorOperand, which could be misused because it's
not necessarilly forwarding ownership.

Remove the isTransformationTerminator API, which is not useful or well
defined.

Rewrite several instances of complex logic to handle block arguments
with the simple terminator result API. This defines away potential
bugs where we don't detect casts that perform implicit conversion.

Replace uses of the SILPhiArgument type and code that explicitly
handle block arguments. Control flow is irrelevant in these
situations. SILPhiArgument needs to be deleted ASAP. Instead, use
simple APIs like SILArgument::isTerminatorResult(). Eventually this
will be replaced by a TerminatorResult type.
2022-12-12 12:37:35 -08:00
Meghana Gupta
ebd7a90587 NFC: Remove unused code + reorg 2022-10-19 19:54:28 -07: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
Andrew Trick
eee184ae4e Delete isValueAddressOrTrivial
If we want a short-circuit test for address types, that should be done
within getOwnershipKind() itself.
2022-10-05 06:30:02 -07:00
Andrew Trick
6861b318ca Make PrunedLiveness::computeSimple one-level transitive
Computing simple liveness is distinct from computing transitive
liveness. But for safety and consistency, always handle the first
level of liveness transitively. This way, computeSimple can be used on
guaranteed values that need OSSA lifetime fixup.

Simple liveness just means that *inner* borrow and address scopes are
assumed to be complete.

This utility is still only used conservatively because OSSA lifetime
completion is not yet enabled. But, in the future, computeSimple can
be used in the common case.
2022-10-04 13:27:48 -07:00
Andrew Trick
6346bf55c5 Rename areUsesWithinTransitiveScope to ...ExtendedScope
Start using consistent terminolfy in ownership utils.

A transitive use set follows transitive uses within an ownership
lifetime. It does not rely on complete inner scopes. An extended use
set is not necessarilly transitive but does look across
lifetime-ending uses: copies of owned values and/or reborrows of
guaranteed values. Whether lifetime extension refers to copies or
reborrow is context dependent.
2022-10-04 13:27:48 -07:00
Andrew Trick
da4f1b9a70 Add InnerBorrowKind and AddressUseKind to PrunedLiveness API
The API for computing simple liveness now returns a
SimpleLiveRangeSummary. Callers need to decide how to handle reborrows
and pointer escapes. If either condition exists then the resulting
liveness does not necessarily encapsulate the definition's ownership.

Fixes some number of latent bugs w.r.t. liveness clients.
2022-10-04 13:27:47 -07:00
Andrew Trick
4ef7f8590f Fix findTransitiveUsesForAddress to handle incomplete scopes
This fixes ScopedAddressValue::computeLiveness in unreachable code scenarios.
For example:

   %storeBorrow = store_borrow %_ to %adr
   %loadBorrow  = load_borrow %storeBorrow
   apply %f(%loadBorrow) : $@convention(thin) (...) -> Never

Now recursively process uses of load_borrow as if they are address
uses.

Ultimately, this would be more efficiently handled by a recursive
lifetime completion utility which would fixup the load_borrow scope
before computing the store_borrow liveness.

Fixes rdar://99874173: unreachable assert "No user in LiveWithin block"
2022-10-04 13:27:47 -07:00
Andrew Trick
40e03ef782 Update passes to use SSAPrunedLiveness or MultiDefPrunedLiveness 2022-10-04 13:27:47 -07:00
Andrew Trick
ca503b54b7 Redesign PrunedLiveness APIs, introducing live ranges
First restore the basic PrunedLiveness abstraction to its original
intention. Move code outside of the basic abstraction that polutes the
abstraction and is fundamentally wrong from the perspective of the
liveness abstraction.

Most clients need to reason about live ranges, including the def
points, not just liveness based on use points. Add a PrunedLiveRange
layer of types that understand where the live range is
defined. Knowing where the live range is defined (the kill set) helps
reliably check that arbitrary points are within the boundary. This
way, the client doesn't need to be manage this on its own. We can also
support holes in the live range for non-SSA liveness. This makes it
safe and correct for the way liveness is now being used. This layer
safety handles:

- multiple defs
- instructions that are both uses and defs
- dead values
- unreachable code
- self-loops

So it's no longer the client's responsibility to check these things!

Add SSAPrunedLiveness and MultiDefPrunedLiveness to safely handle each
situation.

Split code that I can't figure out into
DiagnosticPrunedLiveness. Hopefully it will be deleted soon.
2022-10-04 13:27:44 -07:00
Andrew Trick
dab44e3e86 Fix LexicalDestroyHoisting: avoid optimizing when ownership escapes
Fix the utilities used by LexicalDestroyHoisting that finds all uses
to report a "PointerEscape". We can't rely on lifetime analysis when
such a use is present.
2022-09-30 15:20:52 -07:00
Meghana Gupta
6c0c3dd1e1 Rename hasEscaped -> hasPointerEscape, and don't consider OperandOwnership::BitwiseEscape as a pointer escape 2022-09-15 16:40:39 -07:00
Meghana Gupta
88782ac939 Don't shrink escaped borrow scopes in DCE 2022-09-14 21:02:02 -07:00
Michael Gottesman
467b742a5c [move-only] Update the non-address move checker part of the optimizer to handle mark_must_check on addresses. 2022-09-09 13:38:18 -07:00
Meghana Gupta
98fa7f079f Handle ValueMetatypeInst as a leaf user in swift::findTransitiveUsesForAddress 2022-08-16 15:08:23 -07:00
Meghana Gupta
5244e6f3d5 Improve verification for store_borrow
Add ScopedAddressOperand and ScopedAddressValue abstraction utilities
Introduce verification for store_borrow to validate its uses are correctly enclosed in their scope.

Include end_borrow/end_access as implicit uses while validating a borrow introducer

Add flow sensitive verifier rule for store_borrow/end_borrow pair

Make sure store_borrow is always to an alloc_stack

Make sure uses to store borrow location are via its return address only
2022-08-16 15:08:22 -07:00
Michael Gottesman
1e6187c4f4 [sil] Update all usages of old API SILValue::getOwnershipKind() in favor of new ValueBase::getOwnershipKind().
Andy some time ago already created the new API but didn't go through and update
the old occurences. I did that in this PR and then deprecated the old API. The
tree is clean, so I could just remove it, but I decided to be nicer to
downstream people by deprecating it first.
2022-07-26 11:46:23 -07:00
Nate Chandler
fe435312a1 [OwnershipUtils] Visit owned phi's reborrows.
The new utility, given an phi, visits all adjacent phis (i.e. arguments
to the same block) which are (potentially iterated) reborrows of a value
reaching the given phi.
2022-07-21 15:03:43 -07:00
Meghana Gupta
742052a063 Update PrunedLiveness
- To detect instructions occuring before definition
- To handle reborrows
2022-06-30 10:31:20 -07:00