Commit Graph

48 Commits

Author SHA1 Message Date
Nate Chandler
5da38cb04b [NFC] OSSACanonicalizeGuaranteed: Renamed. 2025-08-18 09:45:27 -07:00
Nate Chandler
8f1d6616af [NFC] OSSACanonicalizeOwned: Renamed. 2025-08-18 09:45:21 -07:00
Nate Chandler
2d1bdb84e6 [Gardening] Add missing word in comment. 2024-12-02 14:05:40 -08:00
Nate Chandler
6e48e05ece [Test] Fix shrink_borrow_scope. 2024-12-02 14:05:40 -08: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
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
e912c036f6 [Reachability] NFC: Split initial from barrier.
Although by analogy with def instructions as barrier instructions one
could understand how a block where the def appears as a phi could be
regarded as a barrier block, the analogy is nonobvious.

Reachability knows the difference between an initial block and a barrier
block.  Although most current clients don't care about this distinction,
one does.  Here, Reachability calls back with visitInitialBlock for the
former and visitBarrierBlock for the latter.

Most clients are updated to have the same implementation in both
visitBarrierBlock and visitInitialBlock.  The findBarriersBackward
client is updated to retain the distinction and pass it on to its
clients.  Its one client, CanonicalizeOSSALifetime is updated to have a
simpler handling for barrier edges and to ignore the initial blocks.
2023-09-14 17:11:20 -07:00
Nate Chandler
ad9fee2883 [Test] Ensourced shrink-borrow-scope.
Moved the test next to the code it calls.
2023-07-04 11:52:13 -07:00
Nate Chandler
4d4042931b [Reachability] NFC: Allow more initial blocks.
Allow clients to specify any number (an array) of blocks beyond which
dataflow won't propagate rather than 1 or 0 (a pointer).
2023-03-25 12:27:57 -07:00
nate-chandler
9c17447158 Merge pull request #61654 from nate-chandler/shrink_borrow_scope/handle_barrier_merge_terminators
Removed deinit barrier workaround.
2022-10-24 14:40:21 -07:00
Nate Chandler
070632a195 [ShrinkBorrowScope] Added assertion.
Checked that a barrier terminator's successor isn't a merge point.
2022-10-24 08:46:47 -07:00
Nate Chandler
8bb465a7ef [Gardening] Fixed comment. 2022-10-24 08:32:56 -07:00
Nate Chandler
a4d31a468b [ShrinkBorrowScope] Leave under rewritten copies.
When shrinking a borrow scope like

    %borrow = begin_borrow %value
    barrier
    %copy = copy_value %borrow
    end_borrow %borrow

the copy will be rewritten to be a copy of the borrowee:

    %borrow = begin_borrow %value
    barrier
    %copy = copy_value %value
                       ^^^^^^
    end_borrow %borrow

If, as here, shrinking next encounters a barrier, then the insertion
point will be that rewritten copy_value instruction.

In such a case, when rather than creating a new end_borrow there and
deleting the old, just reuse the old one.  The lifetime of the value
being copied will be canonicalized by CopyPropagation regardless.
2022-10-20 18:09:54 -07:00
Nate Chandler
f85074d1ba [ShrinkBorrowScope] Barriers use callee analysis.
Pass a BasicCalleeAnalysis instance to isDeinitBarrier.  This will allow
ShrinkBorrowScope to hoist end_borrows over applies of functions which
are not deinit barriers.
2022-10-18 21:23:22 -07:00
Nate Chandler
7ea336367d [NFC] Port isDeinitBarrier to Swift.
Added new C++-to-Swift callback for isDeinitBarrier.

And pass it CalleeAnalysis so it can depend on function effects.  For
now, the argument is ignored.  And, all callers just pass nullptr.

Promoted to API the mayAccessPointer component predicate of
isDeinitBarrier which needs to remain in C++.  That predicate will also
depends on function effects.  For that reason, it too is now passed a
BasicCalleeAnalysis and is moved into SILOptimizer.

Also, added more conservative versions of isDeinitBarrier and
maySynchronize which will never consider side-effects.
2022-10-18 21:23:22 -07:00
Nate Chandler
4fc42a63a3 [CanonicalizeOSSALifetime] Renamed file.
Matched to the name of the utility.
2022-10-05 17:07:05 -07:00
Josh Soref
730b16c569 Spelling siloptimizer
* access
* accessed
* accesses
* accessor
* acquiring
* across
* activated
* additive
* address
* addresses'
* aggregated
* analysis
* and
* appropriately
* archetype
* argument
* associated
* availability
* barriers
* because
* been
* beginning
* belongs
* beneficial
* blocks
* borrow
* builtin
* cannot
* canonical
* canonicalize
* clazz
* cleanup
* coalesceable
* coalesced
* comparisons
* completely
* component
* computed
* concrete
* conjunction
* conservatively
* constituent
* construct
* consuming
* containing
* covered
* creates
* critical
* dataflow
* declaration
* defined
* defining
* definition
* deinitialization
* deliberately
* dependencies
* dependent
* deserialized
* destroy
* deterministic
* deterministically
* devirtualizes
* diagnostic
* diagnostics
* differentiation
* disable
* discipline
* dominate
* dominates
* don't
* element
* eliminate
* eliminating
* elimination
* embedded
* encounter
* epilogue
* epsilon
* escape
* escaping
* essential
* evaluating
* evaluation
* evaluator
* executing
* existential
* existentials
* explicit
* expression
* extended
* extension
* extract
* for
* from
* function
* generic
* guarantee
* guaranteed
* happened
* heuristic
* however
* identifiable
* immediately
* implementation
* improper
* include
* infinite
* initialize
* initialized
* initializer
* inside
* instruction
* interference
* interferes
* interleaved
* internal
* intersection
* intractable
* intrinsic
* invalidates
* irreducible
* irrelevant
* language
* lifetime
* literal
* looks
* materialize
* meaning
* mergeable
* might
* mimics
* modification
* modifies
* multiple
* mutating
* necessarily
* necessary
* needsmultiplecopies
* nonetheless
* nothing
* occurred
* occurs
* optimization
* optimizing
* original
* outside
* overflow
* overlapping
* overridden
* owned
* ownership
* parallel
* parameter
* paths
* patterns
* pipeline
* plottable
* possible
* potentially
* practically
* preamble
* precede
* preceding
* predecessor
* preferable
* preparation
* probably
* projection
* properties
* property
* protocol
* reabstraction
* reachable
* recognized
* recursive
* recursively
* redundant
* reentrancy
* referenced
* registry
* reinitialization
* reload
* represent
* requires
* response
* responsible
* retrieving
* returned
* returning
* returns
* rewriting
* rewritten
* sample
* scenarios
* scope
* should
* sideeffects
* similar
* simplify
* simplifycfg
* somewhat
* spaghetti
* specialization
* specializations
* specialized
* specially
* statistically
* substitute
* substitution
* succeeds
* successful
* successfully
* successor
* superfluous
* surprisingly
* suspension
* swift
* targeted
* that
* that our
* the
* therefore
* this
* those
* threshold
* through
* transform
* transformation
* truncated
* ultimate
* unchecked
* uninitialized
* unlikely
* unmanaged
* unoptimized key
* updataflow
* usefulness
* utilities
* villain
* whenever
* writes

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>
2022-10-03 18:31:33 -04:00
Nate Chandler
39ba0bc19d [NFC] Silenced unused private field warning.
Removed the field.
2022-06-13 10:27:58 -07:00
Nate Chandler
8775148f7b [SILOpt] Used SetVector for fast contains check.
IterableBackwardReachability just requires an iterable list of gens.
ShrinkBorrowScope, LexicalDestroyHoisting, and SSADestroyHoisting all
need to be able to check whether a given instruction is scope ending
quickly.  Use a SmallSetVector rather than a SmallVector for the gens in
all three.
2022-05-24 14:15:27 -07:00
Nate Chandler
3c7ad6013a [ShrinkBorrowScope] Adopt VisitBarrierAccessScopes.
Avoids hoisting borrow scopes into unrelated access scopes which could
introduce exclusivity violations.

rdar://93060369
2022-05-24 08:05:13 -07:00
Nate Chandler
180095ae3a [ShrinkBorrowScope] Adopt iterative dataflow.
Adopt IterativeBackwardReachability.  Enables hoisting end_borrow
instructions over loops.  That in turn enables hoisting destroy_values
over those same loops.

rdar://93186505
2022-05-24 08:05:13 -07:00
Nate Chandler
bdc1f404e6 [Gardening] Recapitalized type. 2022-05-24 08:05:13 -07:00
nate-chandler
0011b075fa Merge pull request #41387 from nate-chandler/lexical_lifetimes/destroy_hoisting/add
Hoist destroys of owned lexical values.
2022-02-17 11:36:50 -08:00
Nate Chandler
1e820068a4 [ShrinkBorrowScope] Don't hoist over begin_borrows.
While it is sometimes valid to hoist over begin_borrows of copies of the
borrowee, it is not always valid, as the test case committed here
illustrates.  As a future optimization, we can reenable this hoisting
with the appropriate condition.
2022-02-16 22:25:55 -08:00
Nate Chandler
2c4f14b1d7 [ShrinkBorrowScope] Replaced check with assertion.
Previously, it was checked whether a barrier terminator was actually a
control flow terminator before adding end_borrows at the beginnings of
its successors.  But it can't actually happen that a terminator is
classified as a barrier without the beginnings of all of its
predecessors having been reached because the BackwardReachability data
flow is pessimistic and only visits the end of a block (i.e. its
terminator) if it reached the beginnings of all of that block's
successors (see BackwardReachability::meetOverSuccessors and where the
data flow calls it).
2022-02-16 10:31:24 -08:00
Nate Chandler
208743c38e [ShrinkBorrowScope] Replaced map with set.
The keys weren't used.
2022-02-16 10:31:24 -08:00
Nate Chandler
41fdbc1285 [ShrinkBorrowScope] Adopt BackwardReachability.
Replaced ShrinkBorrowScope's own data flow with the general
BackwardReachability.

Took this opportunity to refactor and document the utility.

Taken together these changes make ShrinkBorrowScope serve as a template
for a future LexicalDestroyHoisting which will operate on owned lexical
values (rather than guaranteed as here) and hoist destroy_values (rather
than end_borrows as here) but should otherwise be quite similar.
2022-02-14 18:38:31 -08:00
Nate Chandler
8d28beccd8 [ShrinkBorrowScope] Used extract deinit barrier implementation.
In 0325e296fe, the implementation of
deinit barrier predicate was copied out of ShrinkBorrowScope into
MemAccessUtils.  Delete the source of that copy from ShrinkBorrowScope
and just call the now common utility.
2022-01-31 16:36:13 -08:00
Nate Chandler
d6ab2159a9 [NFC] Renamed helper function. 2022-01-31 16:36:03 -08:00
Nate Chandler
3ba8a93c48 [ShrinkBorrowScope] Don't hoist over any applies.
Previously, hoisting was done over applies that were users of the
borrowed value.  Here, that is no longer done.

That hoisting was done on the theory that multiple distinct lexical
scopes were equivalent to a single enclosing lexical scope.  Dead borrow
elimination, however, means that they are not in fact the same, however:
If a callee takes an object as an argument, and in that callee that
argument is dead, FSO and inliniing (even with approaches to maintain
lexical borrow scopes when the value that is borrowed comes from an
owned argument) can result in a dead borrow scope in the caller which
could then be eliminated which would then enable the destroy_value
to be hoisted over the inlined body, including over barriers.
2022-01-07 09:36:40 -08:00
Nate Chandler
9166233713 [NFC] [ShrinkBorrowScope] Used standard assert. 2022-01-07 09:36:36 -08:00
Nate Chandler
4eea76251c [NFC] [ShrinkBorrowScope] Moved check.
Previously, the body--of the loop that iterated the instructions in the
block--contained the check that the instruction over which hoisting
might be done is the introducer.  Here, that check is moved into
tryHoistOverInstruction.  Now that function and its other caller,
canHoistOverInstruction, will return the right value (false) if they are
ever called with the introducer (though that could not happen without
this change).
2022-01-07 09:36:33 -08:00
Nate Chandler
61a3f1431b [ShrinkBorrowScope] Fixed assert.
Previously, it was asserted that hoisting over a terminator succeeded
(because it is previously checked that it can be done).  That was
erroneously done by putting the call to hoist within an invocation of
the assert macro.  The result was that in release builds, the call was
not made.  Here, that is fixed by just calling the hoist function and,
in debug builds, asserting its return.

rdar://86809882
2022-01-04 10:53:33 -08:00
Andrew Trick
ec9d4b444f Add SILInstruction::getNextInstruction() and getPreviousInstruction() 2021-12-22 01:54:05 -08:00
Nate Chandler
7c1da20345 [ShrinkBorrowScope] Checked before adding preds.
Previously, after determining that a block was dead, all its
predecessors were added to the worklist.  That is a problem, with the
current algorithm, if any of the predecessors have a terminator over
which the borrow scope cannot be shrunk.  Here, before adding a dead
block's predecessors to the worklist of blocks through which to shrink,
ensure that all those predecessors have terminators over which the scope
can be shrunk.  Finally, when beginning to process a block, if it
doesn't have a starting instruction, first hoist over thet terminator.
2021-12-19 08:14:46 -08:00
Nate Chandler
c88b0438bd [ShrinkBorrowScope] Enable querying hoistability. 2021-12-19 08:14:46 -08:00
Nate Chandler
a9caa6c150 [Gardening] Doc'd field. 2021-12-19 08:14:46 -08:00
Nate Chandler
9784d0654a [ShrinkBorrowScope] Avoid spurious mutation.
If an end_borrow cannot be hoisted, do not rewrite it.
2021-12-19 08:14:46 -08:00
Nate Chandler
b1cf141905 [Gardening] Improved variable name. 2021-12-19 08:14:45 -08:00
Nate Chandler
4e5e0c748f [Gardening] Improved variable name. 2021-12-19 08:14:45 -08:00
Nate Chandler
c222af3415 [Gardening] Doc'd field. 2021-12-19 08:14:45 -08:00
Nate Chandler
4ab9a2c1cb [NFC] Demoted variable to function scope.
The blocksWithReachedTops variable is only ever used while finding
barriers and in a small helper function called at that time.  Make it
local to that function and make that helper a lambda in that function.
2021-12-19 08:14:45 -08:00
Nate Chandler
1c106eb6e8 [ShrinkBorrowScope] Return modified copy_values.
So that CopyPropagation and other clients can react accordingly, pass
back a list of copy_value instructions that were rewritten by
ShrinkBorrowScope.  In CopyPropagation, add each modified copy to the
copy worklist.
2021-12-19 08:14:45 -08:00
Nate Chandler
8847beb7eb [Gardening] Improved variable name. 2021-12-19 08:14:45 -08:00
Nate Chandler
148e166196 [OwnershipUtils] Repurpose utility.
Replaced findInnerTransitiveGuaranteeedUsesOfBorrowedValue with
findExtendedUsesOfSimpleBorrowedValue.  Starting from a borrowed value,
it finds all extended (i.e., seeing through copies) uses of the borrow
and its projections within the simple (i.e. without considering
reborrowing) borrow scope.
2021-12-19 08:14:45 -08:00
Nate Chandler
8e52f211f3 [ShrinkBorrowScope] Hoist over copies of borrow. 2021-12-19 08:14:45 -08:00
Nate Chandler
3e8948e720 [CopyPropagation] Hoist lexical end_borrows over some applies. 2021-12-07 09:43:58 -08:00
Nate Chandler
cde250a3e3 [CopyPropagation] Add ShrinkBorrowScope.
During copy propagation (for which -enable-copy-propagation must still
be passed), also try to shrink borrow scopes by hoisting end_borrows
using the newly added ShrinkBorrowScope utility.

Allow end_borrow instructions to be hoisted over instructions that are
not deinit barriers for the value which is borrowed.  Deinit barriers
include uses of the value, loads of memory, loads of weak references
that may be zeroed during deinit, and "synchronization points".

rdar://79149830
2021-12-07 09:43:57 -08:00