Commit Graph

64 Commits

Author SHA1 Message Date
Meghana Gupta
04293732cf Add new apis to OwnershipLifetimeExtender 2021-11-01 14:03:16 -07:00
Kuba Mracek
8158cdf5e5 Revert "Merge pull request #39805 from atrick/oou-opt-rauw"
This reverts commit df26a6d740, reversing
changes made to f9643fd3a2.
2021-10-22 12:29:10 -07:00
Andrew Trick
463922c386 Allow RAUW to optimize struct_extract from function args 2021-10-18 14:16:40 -07:00
Andrew Trick
698ed8e043 Make Ownership RAUW checks more precise - allows more optimization.
Call findOwnershipReferenceRoot when checking for guaranteed values
from SILFunctionArgument.

TODO: We need to add a component path to a reference root abstraction
to handle references that come from a struct_extract or tuple_extract.
2021-10-18 14:16:39 -07:00
Andrew Trick
36fb073c21 OSSA RAUW prepareUnowned - short-circuit empty uses
Avoid generating useless empty copies and borrow scopes.

Bypass all the use-checking logic when there are no uses to avoid
special cases and bugs.
2021-10-18 09:01:15 -07:00
Andrew Trick
652ff78412 OSSA RAUW helper redesign - split prepareReplacement() vs. perform()
Required to fix SILCombine.

Divide the logic into smaller pieces. This allows passes to check for
replaceability before generating the replacement value.

Preparation for simplifying OSSA utilities into smaller logical
components making them flexibile and allowing improvements to be
staged in.
2021-10-18 09:01:15 -07:00
Andrew Trick
4a85e187ca Eliminate unused and incomplete OSSA logic. 2021-10-18 09:01:15 -07:00
Andrew Trick
8062e408ea Migrate to OwnershipLifetimeExtender API: borrowCopyOverScope etc.
Preparation for rewriting non-trivial terminators and generalizing
support for guaranteed phis.

Add guaranteedUsePoints to the RAUW context. This will replace ALL
existing context book-keeping once the old code is deleted.

Introduce a borrowCopyOverScope entry point to handle extending
lifetime over a BorrowedValue. This simply uses the
BorrowedLifetimeExtender.

Introduce higher-level APIs:
- borrowOverValue to extened over a guaranteedValue
- borrowOverSingleUse to extened over a single guaranteed use

These replace both createPlusZeroBorrow and createPlusOneBorrow.

Update RAUW-ctor, RAUW::handleUnowned, and replaceAddressUses to use
the new API.

Restructure RAUW::canFixUpOwnershipForRAUW. Simply use
findInnerTransitiveGuaranteedUses.

Replace RAUW::handleGuaranteed and rewriteReborrows with
OLE::borrowOverValue.

Use the BorrowedLifetimeExtender utility to handle all situations
correctly.

TODO: createPlusOneBorrow can be completely removed, and a massive
amount of confusing/incomplete code can be deleted in a follow-up
commit.
2021-10-18 09:01:15 -07:00
Andrew Trick
850426514a Merge pull request #39761 from atrick/fix-accessopt
Fix AccessEnforcementOpts for OSSA
2021-10-15 00:14:23 -07:00
Andrew Trick
4b592c09d8 Add OSSA utilities for extending lifetimes and borrow scopes
Without introducing any new borrow scopes or owned lifetimes.

Top-level APIs:
- extendOwnedLifetime()
- extendLocalBorrow()

New utilitiy: GuaranteedOwnershipExtension.

This is a simple utility to determine whether new uses can be added to
an existing guaranteed value. It reports the kind of transformation
needed and performs the transformation if requested. If transformation
is needed, it simply calls one of the two top-level APIs.
2021-10-14 13:53:37 -07:00
Andrew Trick
d27d83a8f2 CSE/OSSA avoid endless cloning and reoptimization.
Prevent CSE from introducing useless copies, borrows, and
clones. Otherwise it will endlessly clone and re-cse the same
projections endlessly.

TODO: Most of these cases can be handled GuarateedOwnershipExtension
or extendOwnedLifetime without requiring any copies!
2021-10-13 21:56:46 -07:00
Andrew Trick
bdfcc609eb Add a createBorrowScopeForPhiOperands bailout
Avoid using GuaranteedPhiBorrowFixup on phis that cannot possibly have
any guaranteed operands.
2021-10-13 10:57:16 -07:00
Andrew Trick
14e9a01ef7 BorrowedLifetimeExtender minor cleanup 2021-10-13 10:57:16 -07:00
Andrew Trick
d71e450903 Comment OSSA RAUW createBorrowScopeForPhiOperands 2021-10-13 10:57:16 -07:00
Andrew Trick
58a25017f2 OwnershipLifetimeExtender::createPlusOneCopy comments 2021-10-13 10:57:16 -07:00
Andrew Trick
19c8cf12dc Move hasValidRAUWOwnership & canFixUpOwnershipForRAUW
Move the code that sets up the context above all the code that
depends on that context.

This helps keep the relationship straight between several
sub-utilities and gradually clean them up.
2021-10-13 10:57:15 -07:00
Andrew Trick
4cdcc14885 Prepare OwnershipRAUWHelper support for terminator results.
The 'oldValue' can now be a terminator result instead of a
SingleValueInstruction.
2021-10-13 10:57:15 -07:00
Andrew Trick
1f94525478 Remove unused Builders from OwnershipRAUWUtility::handleUnowned 2021-10-13 10:57:15 -07:00
Andrew Trick
ed80028b00 Add an assert to createPlusZeroBorrow
If this doesn't hold, it silently miscompiles.
2021-10-13 10:57:15 -07:00
Andrew Trick
d61732969a Make hasValidRAUWOwnership a static member of OwnershipRAUWHelper
Allow quickly checking for valid OSSA value substitution independent
from information about the value's lifetime or scope. Make it a static
member to allow this to check to be done outside of the RAUW
utility. e.g. from SimplifyCFG.
2021-10-13 10:57:15 -07:00
Andrew Trick
a2b6f7cb3b Fix comment typos 2021-10-13 10:57:15 -07:00
Andrew Trick
b4a47b6463 Fix findInnerTransitiveUsesForAddress; add AddressUseKind
findInnerTransitiveUsesForAddress was incorrectly returning true for
pointer escapes.

Introduce enum AddressUseKind { NonEscaping, PointerEscape, Unknown };

Clients need to handle each of these cases differently.
2021-10-12 19:58:11 -07:00
Andrew Trick
a336bcdea9 Fix findTransitiveUses to only record leaf uses.
Recording uses is now optional. This utility is also used simply to
check for PointerEscape. When uses are recorded, they are used to
extend a live range. There could be a large number of transitive uses
that we don't want to pass back to the caller.
2021-10-12 19:58:10 -07:00
Andrew Trick
8ba105f5cb Use AddressOwnership in OSSA RAUW. Improves optimization.
This mainly simplifies the utility, but also improves optimization as
a side effect.

Update OSSA RAUW after replacing BorrowedAddress with AddressOwnership.

InteriorPointer is no longer needed. This simplifies the fixup
context. Eventually the fixup context will be very lightweight. This
is just the first step.
2021-10-07 15:48:25 -07:00
Andrew Trick
767e094cfe Add AddressOwnership OSSA utility
This replaces the recent BorrowedAddress utility (the address may not
be borrowed!)

APIs:

AddressOwnership::hasLocalOwnershipLifetime() - convenience on top of
AccessBase::hasLocalOwnershipLifetime().

AddressOwnership::getOwnershipReferenceRoot() - convenience on top of
AccessBase::getOwnershipReferenceRoot().

AddressOwnership::findTransitiveUses() - wrapper API over the internal
helper findTransitiveUsesForAddress()

AddressOwnership::areUsesWithinLifetime() - wrapper adds a quick check
on top of BorrowedValue::areUsesWithinLifetime()
2021-10-07 15:34:09 -07:00
Andrew Trick
ffb7ecc1f7 Add a BorrowedLifetimeExtender utility.
Handle SSA update (phi creation) when extending an owned lifetime over
a borrowed lifetime.

This is a layer of logic above BorrowedValue but below
OwnershipLifetimeExtender and other higher-level utilities.
2021-09-17 20:09:58 -07:00
Meghana Gupta
5c684042f0 Fix debug location is some ownership utils (#39148)
Insert point may have invalid LocationKind. Use auto-generated loc.
2021-09-02 17:13:37 -07:00
Meghana Gupta
d40c915489 Fix ownership rauw to not leave behind stale ownership fixup context
Ownership rauw uses a shared ownership fixup context to maintain state.
When ownership rauw fails, due to some invalid condition, we leave
behind stale data in this shared ownership fixup context.
This stale context can indvertantly affect the next rauw on addresses.
In addition to setting the ownership fixup context to nullptr, we
should also clear it so that it's internal data structures are
cleared.
2021-08-12 16:46:20 -07:00
Andrew Trick
a6cb54511a Add a tiny BorrowedAddress utility.
Determines whether an address might be inside a borrowed scope. If so,
then any address substitution needs to find that scope boundary to
avoid violating its basic guarantee that all uses are within scope.
2021-08-09 11:43:41 -07:00
Erik Eckstein
2385a97c79 SILSSAUpdater: use the InstructionDeleter utility for deleting branch instructions.
the SSA updater replaces branch instructions when adding phi arguments. For deleting the old instruction use the InstructionDeleter utility.
2021-07-08 15:29:14 +02:00
Andrew Trick
573df892e7 Fix BorrowingOperand more.
Don't allow an owned call argument to be considered a valid BorrowingOperand.

More generally, make sure there is a perfect equivalence between valid
BorrowingOperand and the corresponding OperandOwnership kind.
2021-06-30 15:20:19 -07:00
Andrew Trick
e9d0b08706 Add utilities to support OSSA update after running SSAUpdater.
This directly adds support to BasicBlockCloner for updating OSSA.

It also adds a much more general-purpose GuaranteedPhiBorrowFixup
utility which can be used for more complicated SSA updates, in which
multiple phis need to be created. More generally, it handles adding
nested borrow scopes for guaranteed phis even when that phi is used by
other guaranteed phis.
2021-03-18 00:14:13 -07:00
Andrew Trick
66752e9724 OSSA: Rewrite address cloning code to fix issues.
Generalize the AccessUseDefChainCloner in MemAccessUtils. It was
always meant to work this way, just needed a client.

Add a new API AccessUseDefChainCloner::canCloneUseDefChain().

Add a bailout for begin_borrow and mark_dependence. Those
projections may appear on an access path, but they can't be
individually cloned without compensating.

Delete InteriorPointerAddressRebaseUseDefChainCloner.

Add a check in OwnershipRAUWHelper for canCloneUseDefChain.

Add test cases for begin_borrow and mark_dependence.
2021-02-24 22:18:21 -08:00
Michael Gottesman
658ce47636 [sil-combine] Allow for storage casts to be cloned when rebasing an address def-use chain onto a new interior pointer 2021-02-24 13:19:39 -08:00
Meghana Gupta
8807d44211 Remove an llvm_unreachable in ownership rauw
This PR just removes an unnecessary error raised in
OwnershipLifetimeExtender::createPlusOneCopy.
We can ownership rauw a value inside the loop with a value outside the
loop. findJointPostDominatingSet correctly helps create control
equivalent copies inside the loop for replacement.
2021-02-10 15:48:22 -08:00
Michael Gottesman
b16f340595 Merge pull request #35684 from eeckstein/fix-find-jpds
SIL: fix problems in findJointPostDominatingSet and some refactoring
2021-02-02 14:18:22 -08:00
Erik Eckstein
d33ea9f350 SIL: remove the JointPostDominanceSetComputer helper struct.
Instead make `findJointPostDominatingSet` a stand-alone function.
There is no need to keep the temporary SmallVector alive across multiple calls of findJointPostDominatingSet for the purpose of re-using malloc'ed memory. The worklist usually contains way less elements than its small size.
2021-02-02 10:20:35 +01:00
Andrew Trick
b3e76ae8e5 Add PhiOperand and PhiValue types.
This is necessitated by the SILArgument representation. It has the
tragic property that adding unrelated phis invalidates existing
phis. Therefore, the optimizer can't do book-keeping of phi values by
refering directly to SILValues or Operands. Instead, it must only
refer to SILBasicBlocks and argument indices.
2021-02-01 20:15:05 -08:00
Andrew Trick
2095c0cf04 OSSA: Use a public explicit constructor for BorrowedValue. 2021-02-01 18:03:24 -08:00
Andrew Trick
caefb9afaa Centralize and document low-level OSSA utilities
...for handling borrow scopes:

- find[Extended]TransitiveGuaranteedUses

- BorrowingOperand::visit[Extended]ScopeEndingUses

- BorrowedValue BorrowingOperand::getBorrowIntroducingUserResult()

And document the logic.

Mostly NFC in this commit, but more RAUW cases should be correctly
handled now.

Particularly, ensure that we can cleanly handle all manner of
reborrows. This is necessary to ensure both CanonicalizeOSSA and
replace-all-uses higher-level utilities handle all cases.

This generalizes some of the logic in CanonicalizeOSSA so it can be
shared by other high-level OSSA utilities.

These utilities extend the fundamental BorrowingOperand and
BorrowedValue functionality that has been designed recently. It builds
on and replaces a mix of piece-meal functionality that was needed
during bootstrapping. These APIs are now consistent with the more
recently designed code. It should be obvious what they mean and how to
use them, should be very hard to use them incorrectly, and should be
as efficient as possible, since they're fundamental to other
higher-level utilities.

Most importantly, there were several very subtle correctness issues
that were not handled cleanly in a centralized way. There are now a
mix of higher-level utilities trying to use this underlying
functionality, but it was hard to tell if all those higher-level
utilities were covering all the subtle cases:

- checking for PointerEscapes everywhere we need to

- the differences between uses of borrow introducers and other
  guaranteed values

- handling the uses of nested borrow scopes

- transitively handling reborrows

- the difference between nested and top-level reborrows

- forwarding destructures (which can cause exponential explosion)

In short, I was fundamentally confused and getting things wrong before
designing these utilities.
2021-02-01 18:03:24 -08:00
Erik Eckstein
462e58d3cb SILLocation: a big refactoring and reducing its size from 3 to 2 words
My goal was to reduce the size of SILLocation. It now contains only of a storage union, which is basically a pointer and a bitfield containing the Kind, StorageKind and flags. By far, most locations are only single pointers to an AST node. For the few cases where more data needs to be stored, this data is allocated separately: with the SILModule's bump pointer allocator.

While working on this, I couldn't resist to do a major refactoring to simplify the code:

* removed unused stuff
* The term "DebugLoc" was used for 3 completely different things:
    - for `struct SILLocation::DebugLoc` -> renamed it to `FilePosition`
    - for `hasDebugLoc()`/`getDebugSourceLoc()` -> renamed it to `hasASTNodeForDebugging()`/`getSourceLocForDebugging()`
    - for `class SILDebugLocation` -> kept it as it is (though, `SILScopedLocation` would be a better name, IMO)
* made SILLocation more "functional", i.e. replaced some setters with corresponding constructors
* replaced the hand-written bitfield `KindData` with C bitfields
* updated and improved comments
2021-01-29 20:28:21 +01:00
Michael Gottesman
dbd66d8e2d [ownership] Change BorrowingOperand to no longer be convertable to Operand * and provide a conversion to bool instead.
A few notes:

1. We already have provide an operator* that does this and even better makes the
   conversion explicit in the source.

2. The bool operator checks both that kind is not invalid and that the operand
   is non-null. This ensures we can use an `if` to properly check for a valid
   BorrowingOperand.
2021-01-28 12:10:16 -08:00
Michael Gottesman
2fad943df0 [sil-combine] Update convert_function canonicalization for ownership.
Some notes:

1. I moved the identity round-trip case to InstSimplify since that is where
   optimizations like that are.

2. I did not update in this commit the code that eliminates convert_function
   when it is only destroyed. In a subsequent commit I am going to implement
   that in a general way and apply it to all forwarding instructions.

3. I implemented eliminating convert_function with ownership only uses in a
   utility so that I can reuse it for other similar optimizations in SILCombine.
2021-01-28 12:10:16 -08:00
Michael Gottesman
9f952714d3 [ownership] Allow for OwnershipRAUWHelper to RAUW in non-ossa mode to cleanup code.
This just makes it easier to write code that supports both
ownership/non-ownership code.
2021-01-28 12:10:16 -08:00
Erik Eckstein
ddd0f4d3a9 SIL: replace SmallPtrSet<SILBasicBlock *> with BasicBlockSet in LinearLifetimeChecker
This makes it unnecessary to share a single instance of visited blocks across multiple calls the the checker.
2021-01-27 10:31:17 +01:00
Meghana Gupta
78a6213080 Clear context in ownership rauw when we cannot fix ownership for rauw.
If not, subsequent unrelated call of OwnershipRAUWHelper::perform will have stale
entries for transitiveBorrowedUses etc
2021-01-26 20:34:24 -08:00
Meghana Gupta
3e330abf44 Fix use-after-free in ownership rauw
Instead of saving BorrowingOperand on the context save the SILBasicBlock
and index of the terminator operand.
This avoids the use-after-free in eliminateReborrowsOfRecursiveBorrows.
Previously, eliminateReborrowsOfRecursiveBorrows called helper
insertOwnedBaseValueAlongBranchEdge, which can delete a branch
instruction (reborrow) that could have been cached in
recursiveReborrows.
2021-01-26 20:21:16 -08:00
Michael Gottesman
de58e7997b [ownership] When RAUWing an unowned value with a owned/guaranteed value only insert unchecked_ownership_conversion for terminator uses.
Already, we allow for owned/guaranteed values to be passed to values with
unowned ownership. This just cleans up the SIL a bit.

That being said, we still need unchecked_ownership_conversion for the terminator
case since any owned/guaranteed's value (ignoreing function parameters) will end
before the return meaning that we need some way of escaping it.
2021-01-25 18:44:00 -08:00
Michael Gottesman
44fdc746ea [ownership] Allow the user of OwnershipRAUWHelper to insert forwarding transforms of the new value at oldValue in between checking and RAUWing. 2021-01-25 17:18:31 -08:00
Andrew Trick
a2fac95f9f OSSA ownership optimization RAUW utility fixes.
Verify that the OwnershipRAUWUtility always preserves the original
borrow scope by exhaustively switching over OperandOwnership.

And related cleanup.
2021-01-23 18:15:58 -08:00