Unlike non-ossa, ossa's switch_enum accepts an argument for the default case
When all other cases are unreachable, replace the default block's phi with
the switch_enum's operand and transform the switch_enum to a branch.
Fixes rdar://139441002
DCE inserts end_borrow at phi operands when a guaranteed phi becomes dead.
This should be done for reborrows which end the lifetime of the incoming value.
The existing check was not accurate and ended up inserting end_borrow for forwarded values as well.
Fixes rdar://139283745
Make sure that an enum is only initialized once before it is taken. This implies that the initialization must dominate the take.
Fixes a verifier crash: rdar://139381701
In case the control flow ends in a dead-end block there can be begin-borrow instructions which have no corresponding end-borrow uses.
After duplicating such a block, the re-borrow flags cannot be recomputed correctly for inserted phi arguments.
Therefore just disable duplicating such blocks, e.g. in jump-threading.
This API computes the re-borrow flags for guaranteed phis based on the presence of forwarding instructions in the incoming values.
This is not correct in all cases, because optimizations can optimize away forwarding instructions.
Fixes a verifier crash: rdar://139280579
TLDR: Was looking at some performance traces and saw that we need to cache the
result of this value.
----
Specifically, I noticed that we were spending a lot of time computing this
operation. When I looked at the code I saw that we already had a cache along the
relevant code paths... but the cache was from equivalence class representative
-> state. Before we hit that cache, we were performing the work to map the value
to the equivalence class representative... so the work to perform the relevant
lookup from value -> state (which goes through the equivalence class
representative) was not just a hash table lookup. This operation makes it
cheaper by making it two cache lookups.
It may be possible to make this cheaper by redoing the actual mapping of
information so that we can go straight from value to state. I think it would be
slightly different since we would probably need to represent the state in a
separate array and map with indices... which is really just a more efficient
hash table. We could also use malloc/etc but lets not even talk about that.
rdar://139520959
I am going to be adding more functionality to this that moves a bit of the
utilities code into it. So it really makes sense to move it to the top of the
file closer to that code. I am doing this separately to make the other
refactoring easier to see in the diff.
The instruction only deallocates the box, it doesn't destroy its
contents. It's even less mutating than a `destroy_value`, which is
already regarded as non-mutating.
This ended up in creating a lot of Array functions, even if a program didn't use Array at all.
Now, only add specialization attributes if a function is already there.
Otherwise remember the attributes and add them to a function once it is created.
Otherwise optimizations like retain-sinking might create retain_value instructions with a non-copyable operand.
Fixes a compiler crash.
rdar://139103557
I am adding this instruction to express artificially that two non-Sendable
values should be part of the same region. It is meant to be used in cases where
due to unsafe code using Sendable, we stop propagating a non-Sendable dependency
that needs to be made in the same region of a use of said Sendable value. I
included an example in ./docs/SIL.rst of where this comes up with @out results
of continuations.
This problem comes up with the following example:
```swift
class A {
var description = ""
}
class B {
let a = A()
func b() {
let asdf = ""
Task { @MainActor in
a.description = asdf // Sending 'asdf' risks causing data races
}
}
}
```
The specific issue is that the closure we generate actually includes an
implicit(any) parameter at the SIL level which occurs after the callee operand
but before the captures. This caused the captured variable index from the AST
and the one we compute from the partial_apply to differ by 1. So we need to
subtract 1 in such a case. That is why we used to print 'asdf' instead of 'a'
above.
DISCUSSION: This shows an interesting difference between SIL applied arg indices
and AST indices. SIL applied arg indices would include the implicit(any)
parameter since it is a parameter in the SIL function type. In contrast, this
doesn't show up in the formal AST parameters or captures. To make it easier to
reason about this, I added a new API to ApplySite called
ApplySite::getASTAppliedArgIndex and added large comments to
getASTAppliedArgIndex and getAppliedArgIndex that explains the issue.
rdar://136593706
https://github.com/swiftlang/swift/issues/76648
This makes it so that one does not need to deal with the differences in text in
between the task isolated case and the actor isolated case. This is done by
swallowing the entire part of this message in one method rather than having the
caller do the work.
This is going to let me just pass through the error struct to the diagnostic
rather than having the CRTP and then constructing an info object per CRTP.
Currently, to make it easier to refactor, I changed the code in
TransferNonSendable to just take in the new error and call the current CRTP
routines. In the next commit, I am going to refactor TransferNonSendable.cpp
itself. This just makes it easier to test that I did not break anything.