Commit Graph

73 Commits

Author SHA1 Message Date
Andrew Trick
755bce217d Remove complexity in findBoundariesInBlock
We can remove a ton of complexity by assuming that SSA uses never
occur before a def in the same block. This will hold true as long as
useless phis are only removed after all unreachable code is first
removed. Then we don't have the self-loop problem.

The SILVerifier already checks this invariant and I added an in-depth
comment in SimplifyCFG.
2022-10-04 13:27:48 -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
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
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
4b361d5bb6 Merge pull request #61145 from atrick/ossa-nonuse-liveness
Handle OperandOwnerhip::NonUse in PrunedLiveness::computeSSALiveness.
2022-09-16 09:35:08 -07:00
Michael Gottesman
724449d579 [move-only] Add support for trivial move only var/mutating self/inout. 2022-09-15 13:55:03 -07:00
Andrew Trick
e1e59ac621 Handle OperandOwnerhip::NonUse in PrunedLiveness::computeSSALiveness.
Fixes a bug in the simple PrunedLiveness routine for SSA values.

Without this fix, the init_existential_ref instruction below was not
considered a lifetime-ending use because the non-use type dependednt
operand (which is not really an operand at all) would override the
forwarding operand:

  %1 = open_existential_ref %0 : $any P to $@opened("...", any P) Self
  %2 = init_existential_ref %1 : $@opened("...", any P) Self : $@opened("...", any P) Self, $AnyObject

This will be tested by silgen_cleanup_complete_ossa.sil.
2022-09-15 11:13:56 -07:00
Michael Gottesman
0a16cc362a [move-only] Implement an initial version of the move only address checker.
Some notes:

1. I added support for both loadable/address only types.

2. These tests are based off of porting the move only object tests for inout,
vars, mutating self, etc.

3. I did not include already written tests for address only types in this
specific merge since I need to change us to borrow move only var like types.
Without that, we get a lot of spurious error msgs and the burden of writing that
is not worth it. So instead in a forthcoming commit where I fix that issue in
SILGen, I will commit the corresponding address only tests for this work.

4. I did not include support for trivial types in this. I am going to do
object/address for that at the same time.
2022-09-11 18:57:32 -07:00
Michael Gottesman
7c452ca400 [pruned-liveness] Implement FieldSensitiveAddressPrunedLiveness.
This is the same algorithm as pruned liveness but assumes that one is tracking
liveness from an address and uses the same scheme as DI to track liveness as a
bit vector.
2022-08-30 17:25:55 -07:00
Michael Gottesman
e51e17fa5e [pruned-liveness] Change the internal bit-vector to use 2 bits to represent its state instead of 1 + missing value in DenseMap.
The reason why I am doing this is that in order to be able to use
PrunedLivenessBlocks with multiple elements, we can no longer rely on dead being
represented by a block not having any state, since a dead bit could have a
neighboring live bit.

That being said, the only place that this is used now is the current
PrunedLiveness implementation which only stores a single bit... but that still
at least exercises the code and lets us know that it works.
2022-08-22 13:26:34 -07:00
Michael Gottesman
04144d8214 [pruned-liveness] Change PrunedLiveBlocks so that it can propagate multiple bits of liveness rather than just one.
This is useful for making a form of PrunedLiveness that is sensitive to address
fields. I wired up the current PrunedLiveness to just use PrunedLiveBlocks with
num bits set to 1.
2022-08-22 12:11:18 -07:00
Meghana Gupta
742052a063 Update PrunedLiveness
- To detect instructions occuring before definition
- To handle reborrows
2022-06-30 10:31:20 -07:00
Josh Soref
d767912be2 Spelling sil (#42471)
* spelling: accessible

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: accessories

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: allocated

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: amortizes

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: are

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: arguments

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: cacheable

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: check

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: clazz

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: compatible

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: compilation

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: completely

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: construct

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: conversion

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: declarations

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: derivation

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: deserialization

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: destroyed

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: determined

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: different

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: doesn't

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: equality

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: equivalent

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: formation

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: forwards

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: global

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: guaranteed

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: have

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: identify

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: inaccessible

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: indeterminate

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: indices

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: inefficient

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: inheritance

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: instantaneous

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: instruction

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: intentionally

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: interior

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: intrinsic

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: introducing

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: irrelevant

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: message

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: multi

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: necessarily

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: object

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: one

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: optimization

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: otherwise

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: overridden

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: parameter

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: pattern

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: pipeline

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: possibility

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: postdominance

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: providing

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: reached

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: recognized

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: refrigerator

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: remaining

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: resilient

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: retrieve

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: scavenge

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: scheduled

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: separately

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: serializable

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: signature

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: simplicity

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: specifically

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: substituted

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: substitution

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: subtypes

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: supplement

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: syntax

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: the

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: there

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: these

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: this

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: though

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: through

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: transitively

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: transpose

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: trivial

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: value

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: verification

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: visibility

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: weird

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: whole

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

Co-authored-by: Josh Soref <jsoref@users.noreply.github.com>
2022-04-22 15:11:09 -07:00
Andrew Trick
218f33e216 Add a FIXME to remove PrunedLiveness::nonLifetimeEndingUsesInLiveOut
Looks like it was added as a bootstrapping hack but doesn't belong
here and won't work in general.
2022-02-16 12:23:01 -08:00
Nate Chandler
2c0a35aa54 [PrunedLiveness] Added areUsesOutsideBoundary. 2022-02-02 09:58:25 -08:00
Andrew Trick
febde3da2f SemanticARCOpts fix - remove deadEndBlocks checks
SemanticARCOptVisitor::performGuaranteedCopyValueOptimization was
converting this SIL

    %borrow = begin_borrow %copiedValue
    %copy = copy_value %borrow
    %borrowCopy = begin_borrow %copy
    end_borrow %borrow
    end_borrow %borrowCopy
    destroy_value %copy
    // something something
    unreachable

into

    %borrow = begin_borrow %copiedValue
    %innerBorrow = begin_borrow %borrow
    end_borrow %borrow
    end_borrow %innerBorrow
    // something something
    unreachable

Dead-end blocks are simply irrelevant for this
optimization. Unfortunately, there were multiple layers of attempted
workarounds that were hiding the real problem, except in rare cases.

Thanks Nate Chandler for reducing the test.
2021-12-09 20:23:17 -08:00
Michael Gottesman
4aa4ac3027 [moveOnly] Add checker that validates that if a let/param copyable value has _move applied to it, the let doesn't have any later uses.
This is just an initial prototype for people to play with. It is as always
behind the -enable-experimental-move-only flag.

NOTE: In this PR I implemented this only for 'local let' like things (local
lets/params). I did not implement in this PR support for local var and haven't
done anything with class ivars or globals.

rdar://83957028
2021-11-04 17:13:29 -07:00
Andrew Trick
4183abc822 Fix an obvious bug in findLastUserInBlock.
This crept in the last commit because of rebasing but was never used.
2021-10-14 16:51:53 -07:00
Andrew Trick
ab0601d97a Add PrunedLiveness::computeSSALiveness
Straighforward API to build pruned liveness from a single SSA value.

This 3-line function allows PrunedLiveness to be used anywhere
ValueLifetimeAnalysis was used in OSSA form. Aside from simplicity and
efficiency, the difference is that this composes with other utilities
that only care about PrunedLiveBlocks, PrunedLiveness, or
PrunesLivenessBounary independent of how those data structures were generated.
2021-10-06 09:23:17 -07:00
Andrew Trick
c056ca6f7a Add PrunedLivenessBoundary mini-abstraction
Simple wrapper to compute the boundary of PrunedLiveness.

Pervasively useful utility for working with OSSA reference lifetimes
and borrow scopes.

This can also replace the implementation in
CanonicalOSSALifetime. This will greatly simplify that utility's
logic, preparing it to handle diagnostics (like move-only SILValue
checking) and other features.
2021-10-06 09:23:17 -07:00
Andrew Trick
ec64297893 Add PrunedLiveness::isWithinBoundary API
A perfectly straightforward liveness check. Used by OSSA utilities to
check that an instruction is within a lifetime or scope.
2021-10-06 09:23:02 -07:00
Andrew Trick
add3406cfe Move PrunedLiveness so it can be used as a lightweight OSSA helper.
For use in OwnershipUtils.
2021-10-06 09:23:02 -07:00