APIs on ForwardingInstruction should be written as static taking in
a SILInstruction as a parameter making it awkward.
Introduce a ForwardingOperation wrapper type and move the apis from the
old "mixin" class to the wrapper type.
Add new api getForwardedOperands()
We can't remove the functions at this point in case they might have other function
passes enqueued to run on them, but we can at least remove the function contents
that are now unnecessary. We need to do this in cases when move-only types are
involved, since the semantics of the move checker rely on unescaped captures being
promoted before the pass runs, and we leave behind invalid SIL in the unpromoted code.
rdar://110675352
Attribute @_silgen_name is today only allowed to be used on functions, this change allows usage on globals as well. The motivation for that is to be able to "forward declare" globals just like it's today possible to do with functions (for the cases where it's not practical or convenient to use a bridging header).
Separately, this change also adds a @_silgen_name(raw: ...) syntax, which simply avoids mangling the name (by using the \01 name prefix that LLVM uses). The motivation for that is to be able to reference the "magic Darwin linker symbols" that can be used to look up section bounds (in the current dylib/module) -- those symbols don't use the underscore prefix in their mangled names.
The reason why we want to do this is that if we treat it as a true forwarding
use, we will visit the uses of the trivial value and treat those as liveness
uses. Since the trivial value is not tied to the lifetime of the underlying
noncopyable value, this can be outside of the lifetime of said value causing a
memory lifetime error. By just treating the guaranteed forwarding instruction
with all trivial values as a liveness use, we avoid this problem.
I added a SIL test, a Swift test, and an Interpreter test that validates this
behavior.
rdar://111497657
It sets the `[bare]` attribute for `alloc_ref` and `global_value` instructions if their header (reference count and metatype) is not used throughout the lifetime of the object.
The `bare` attribute indicates that the object header is not used throughout the lifetime of the object.
This means, no reference counting operations are performed on the object and its metadata is not used.
The header of bare objects doesn't need to be initialized.
SelectEnumInstBase will be templated in the next commit.
Instead of using templated SelectEnumInstBase everywhere, introduce
a new wrapper type SelectEnumOperation.
Instead of dealing with substitutions during raw SIL lowering,
let's produce a partial apply without argument to produce a
substituted reference that could be used by SILVerifier and
raw SIL lowering stages.
We previously were emitting a consuming partial_apply diagnostic. I had to
reformulate slightly the way we pattern match the diagnostics to make sure that
we get the proper no consume diagnostic.
rdar://111461837
The reason why I am doing this is that this was not part of the original
evolution proposal (it was called an extension) and after some discussion it was
realized that partial consumption would benefit from discussion on the forums.
rdar://111353459
In the next commit, I am modifying the move only checker to ensure that we
always error when partially invalidating. While doing this I discovered that
these copies were getting in the way of emitting good diagnostics in that case.
The address checker records instructions that initialize fields in its
initInsts map. Previously, that map mapped from an instruction to a
range of fields of the type. But an instruction can initialize multiple
discontiguous fields of a single value. (Indeed an attempt to add a
second range that was initialized by an already initializing
instruction--even if it were overlapping or adjacent--would have no
effect and the map wouldn't be updated.) Here, this is fixed by fixing
the representation and updating the storage whenver a new range is seen
to be initialized by the instruction. As in
https://github.com/apple/swift/pull/66728 , a SmallBitVector is the
representation chosen.
rdar://111391893
In preparation for having a third instance getting or creating the bits
affected by an instruction, introduce a typealias for maps
SILInstruction->SmallBitVector and a helper function that returns
a reference to the SmallBitVector for an instruction and two others that
set into those bits the bits from another bit vector or from a range.
The address checker records instructions that reinit fields in its
reinitInsts map. Previously, that map mapped from an instruction to a
range of fields of the type. But an instruction can use multiple
discontiguous fields of a single value. (Indeed an attempt to add a
second range that was reinit'd by an already reinit'ing
instruction--even if it were overlapping or adjacent--would have no
effect and the map wouldn't be updated.) Here, this is fixed by fixing
the representation and updating the storage whenver a new range is seen
to be reinit'd by the instruction. As in
https://github.com/apple/swift/pull/66728 , a SmallBitVector is the
representation chosen.
rdar://111356251
Reformatting everything now that we have `llvm` namespaces. I've
separated this from the main commit to help manage merge-conflicts and
for making it a bit easier to read the mega-patch.
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.
During initializeLiveness, all blocks which contain destroys are to be
recorded in consuming blocks. Previously, however, certain reinits were
not being added. Here, all reinits are correctly added.
The multi-def algorithm is based off the single-def algorithm. However,
it differs from it in needing to handle "liveness holes"--uses before defs.
When identifying blocks which are originally live, the algorithm starts
from consuming blocks and walks backwards until a condition is met.
Previously, that condition was finding blocks which were originally
live. That makes sense in the single-def case: if a block is originally
live, either it was already walked through or else it was one of the
blocks discovered by liveness. In either case, its predecessors have
already been visited if appropriate.
However, in the multi-def case, this condition is too stringent. It
fails to account for the possibility of a block with has a "liveness
hole". Only stop the backwards walk if the predecessor not only (1) was
in originally live but additionally (2) "kills liveness"--doesn't have a
use before a def.
rdar://111221183
* Don't invalidate the lookup cache in 'getOrCreateSynthesizedFile()'
Adding a synthesized file itself doesn't introduce any decls. Instead,
we should invalidate the right after the actual declrations are added
in the file
* Remove 'SourceLookupCache::invalidate()' method. It was just used
right before the destruction. It was just not necessary
* Include auxiliary decls in 'SourceLookupCache::lookupVisibleDecls()'
Previously, global symbol completion didn't include decls synthesized
by peer macros or freestanding decl macros
* Include "auxiliary decls" in visible member lookup, and visible local
decl lookup
* Hide macro unique names
rdar://110535113