Commit Graph

23 Commits

Author SHA1 Message Date
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
9f6c30919b [NFC] SIL: Typed begin_borrow's isLexical. 2024-03-08 22:27:50 -08: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
Andrew Trick
2b70d2dad8 Fix SemanticARCOpts LoadCopyToBorrowOpt for ObjC closure thunk
This fixes a use-after-free miscompile.

LoadCopyToBorrowOpt alias analysis was wrong in
visitArgumentAccess. inout_aliasable does not give you exclusive
access to an address.

This resulted in removal of a retain before calling an ObjC block
after converting it from a Swift closure.

@_silgen_name("foreign")
func foreign(block: @escaping @convention(block) () -> Void)

public func doit(closure: @escaping () -> ()) {
  foreign { [closure] in closure() }
}

Fixes rdar://121268094
2024-01-25 22:13:15 -08:00
Evan Wilde
f3ff561c6f [NFC] add llvm namespace to Optional and None
This is phase-1 of switching from llvm::Optional to std::optional in the
next rebranch. llvm::Optional was removed from upstream LLVM, so we need
to migrate off rather soon. On Darwin, std::optional, and llvm::Optional
have the same layout, so we don't need to be as concerned about ABI
beyond the name mangling. `llvm::Optional` is only returned from one
function in
```
getStandardTypeSubst(StringRef TypeName,
                     bool allowConcurrencyManglings);
```
It's the return value, so it should not impact the mangling of the
function, and the layout is the same as `std::optional`, so it should be
mostly okay. This function doesn't appear to have users, and the ABI was
already broken 2 years ago for concurrency and no one seemed to notice
so this should be "okay".

I'm doing the migration incrementally so that folks working on main can
cherry-pick back to the release/5.9 branch. Once 5.9 is done and locked
away, then we can go through and finish the replacement. Since `None`
and `Optional` show up in contexts where they are not `llvm::None` and
`llvm::Optional`, I'm preparing the work now by going through and
removing the namespace unwrapping and making the `llvm` namespace
explicit. This should make it fairly mechanical to go through and
replace llvm::Optional with std::optional, and llvm::None with
std::nullopt. It's also a change that can be brought onto the
release/5.9 with minimal impact. This should be an NFC change.
2023-06-27 09:03:52 -07:00
Nate Chandler
2163269f88 [SemanticARCOpts] Check uses in moved load range.
In https://github.com/apple/swift/pull/65417 , support for promoting
moved-from `load [copy]`s was added.  At that time, the existing logic
was generalized so that the check for whether writes the loaded-from
address occurred: rather than checking whether the writes occurred in
the live-range of the `load [copy]`, it was generalized to check whether
writes occurred in the live range of the "original" value which was
either the `load [copy]` or the `move_value`.  That opened a hole for
writes that occurred between the `load [copy]` and the `move_value`:

```
%v = load [copy] %a
%u = load [take] %a
%m = move_value %v
```

Here, this is fixed by checking both the live-range of the "original"
and also (supposing the original is different from the `load [copy]`)
also the live range of the `load [copy]`.

This required changing the list of consuming uses passed to the
`LinearLifetimeChecker::usesNotContainedWithinLifetime` to include not
just the `destroy_value`s but also the "unknown" consuming uses (i.e.
those that are not forwarding).

This change only affects arguments (and specifically only `@inout`
arguments since promotion for `@in` arguments isn't supported) because a
totally different code path is followed for `alloc_stack`s which regards
`load [take]`s as an "init" of the address (concretely,
`getSingleInitAllocStackUse` returns `truea for the above example if `%a` is
an `alloc_stack`).

rdar://108745323
2023-05-01 18:30:22 -07:00
Nate Chandler
f039d40086 [SemanticARCOpts] Load_borrow moved load [copy]s.
In the context of promoting a `load [copy]` to a `load_borrow`, allow
the value representing the lifetime of the load to differ from the `load
[copy]` itself--it may either be the load or its only user.

If promoting the `load [copy]` to a `load_borrow` with the load itself
as the lifetime representative fails, look for a single `move_value` use
of the load.  If found, attempt the optimization again with the
`move_value` as the lifetime representative.

rdar://108514447
2023-04-25 11:37:30 -07:00
Nate Chandler
8287d2e9ef [SemanticARC] NFC: Extracted opt from visit.
In preparation to attempt two variations of the optimization, added
performLoadCopyToLoadBorrowOptimization and call it from visitLoadInst.
2023-04-25 11:37:30 -07:00
Andrew Trick
103a6fefb8 LinearLifetimeChecker - make DeadEndBlocks optional 2023-03-01 21:41:46 -08:00
Erik Eckstein
ab1b343dad use new llvm::Optional API
`getValue` -> `value`
`getValueOr` -> `value_or`
`hasValue` -> `has_value`
`map` -> `transform`

The old API will be deprecated in the rebranch.
To avoid merge conflicts, use the new API already in the main branch.

rdar://102362022
2022-11-21 19:44:24 +01:00
Nate Chandler
a1c1b32a8c [MemAccessUtils] Added RelativeAccessStorageWithBase.
The new "relative" version of AccessStorageWithBase carries additional
information about the walk from the specified address back to the base.
For now, that includes the original address and the most transformative
sort of cast that was encountered.
2022-03-14 09:46:02 -07:00
Meghana Gupta
22c288942b Fix OOB access in SemanticARCOpts (#39351) 2021-09-22 18:17:41 -07:00
Andrew Trick
e85228491d Rename AccessedStorage to AccessStorage
to be consistent with AccessPath and AccessBase.

Otherwise, the arbitrary name difference adds constant friction.
2021-09-21 23:18:24 -07:00
Michael Gottesman
85de7c9970 [semantic-arc] Add a comment dexplaining that isSingleInitAllocStack does not necessarily contain operands of destroy_addr now that it handles checked_cast_addr_br, unchecked_checked_cast_addr. 2021-03-29 12:16:49 -07:00
Andrew Trick
b689b1dabe Rename GuaranteedARCOpts to MandatoryARCOpts.
This bleeds into the implementation where "guaranteed" is used
everywhere to talk about optimization of guaranteed values. We need to
use mandatory to indicate we're talking about the pass pipeline.
2021-03-02 22:20:13 -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
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
Michael Gottesman
2ae43f97af [ownership] Eliminate Optional return value APIs from OwnershipUtils in favor of an Invalid enum case.
Should be NFC.
2021-01-14 11:02:10 -08:00
Michael Gottesman
56664088ec [semantic-arc] Expand out the infrastructure for disabling/enabling specific opts and use that to add new split up semantic-arc tests.
This split will ensure we are testing only what a specific optimization is doing
rather than all together.

NOTE: The way I split up the tests is I first split up each of the tests by
subject area by hand that I thought were specifically testing one pass. Then any
tests where the FileCheck tests started to fail due to us not running the other
passes, I put back a copy in the original semantic-arc-opts.sil to ensure we do
not regress.

Note, the tests that I copied for each of these passes
are originally from semantic-arc-opts.sil. I left them there as well so we could
see all of the opts together. I also only copied the ones that were testing pass
specific functionality.
2020-11-25 19:32:01 -08:00
Andrew Trick
b272dc5e1a Cache 'isLet' within AccessedStorage.
Compute 'isLet' from the VarDecl that is available when constructing
AccessedStorage so we don't need to recover the VarDecl for the base
later.

This generally makes more sense and is more efficient, but it will be
necessary when we look past class casts when finding the reference root.
2020-10-16 15:00:10 -07:00
Andrew Trick
1e9c4d13ad Update LoadCopyToLoadBorrow for MemAccessUtils API. 2020-10-16 15:00:10 -07:00
Michael Gottesman
915ccc0854 [semantic-arc] Extract out from the main visitor a context object for individual sub optimizations.
This patch moves state from the main SemanticARCOptVisitor struct to instead be
on a context object. Sub-transformations should not need to know about the
visitor since how it processes things is orthogonal from the transformations
themselves.
2020-09-16 19:11:07 -05:00
Michael Gottesman
ba6dc1724b [semantic-arc] Split load [copy] -> load_borrow opt into its own file. 2020-08-31 10:07:59 -07:00