Narrowly fix a long-standing bug where destroy_addrs would be hoisted
into read access scopes, leaving the scope as a read despite the fact
that it modifies memory. This is a problem for utilities which expect
access scopes to provide correct summaries. Do this by refusing to fold
into access scopes which are marked `[read]`.
In a follow-up, we can reenable this folding, promoting each access
scope to a modify. Doing so requires checking that there are no access
scopes which overlap with any of the access scopes which would be
promoted to modify.
rdar://154407327
A destroy of an `init_enum_data_addr` is not equivalent to a destroy of
the whole enum's address. Treat such destroys just like destroys of
`struct_element_addr`s are treated: by bailing out.
rdar://152431332
Unknown uses of raw pointers should not result in bailing out when an
address is lexical--the destroy of the address will already not be
hoisted over any instructions which may access pointers. If the address
is not lexical however (such as any address when lexical lifetimes are
disabled), that rationale does not apply, so unknown uses of raw
pointers must cause hoisting to bail.
rdar://133969821
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)
Previously, `visitProductLeafAccessPathNodes` required its caller to
provide both an `AccessPath` `path` and an `SILValue` `address` which
satisfied `path == AccessPath::compute(address)` to force the caller to
handle the case of an invalid `AccessPath`. Now, instead, it computes
the value itself and returns false if it's invalid.
It could be tweaked to also return false if the provided lambda returned
false but that would make the only currently extant callers less
pleasant and also would not be sufficient in the case of caller who
wanted to distinguish between an invalid `AccessPath` and a particular
leaf visit returning false.
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.
llvm::SmallSetVector changed semantics
(https://reviews.llvm.org/D152497) resulting in build failures in Swift.
The old semantics allowed usage of types that did not have an
`operator==` because `SmallDenseSet` uses `DenseSetInfo<T>::isEqual` to
determine equality. The new implementation switched to using
`std::find`, which internally uses `operator==`. This type is used
pretty frequently with `swift::Type`, which intentionally deletes
`operator==` as it is not the canonical type and therefore cannot be
compared in normal circumstances.
This patch adds a new type-alias to the Swift namespace that provides
the old semantic behavior for `SmallSetVector`. I've also gone through
and replaced usages of `llvm::SmallSetVector` with the
`Swift::SmallSetVector` in places where we're storing a type that
doesn't implement or explicitly deletes `operator==`. The changes to
`llvm::SmallSetVector` should improve compile-time performance, so I
left the `llvm::SmallSetVector` where possible.
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.