It's like Builtin.gep, but marks the resulting `index_addr` as a projection, meaning the result can only reach the single element at the given index and cannot be used for general pointer arithmetic by chaining `index_addr` instructions.
This PR introduces a new Swift builtin `Builtin.dereferenceable` that
allows the compiler to provide dereferenceable memory hints to LLVM for
optimization purposes.
Resolves rdar://174255636
AFAIR we were using the "enter task cancel cleanup" in async let to
cancel tasks, however this moved to enterAsyncLetCleanup. There is no
uses of the cancel cleanup anymore.
The Task.cancel was using the builtin, but the UnsafeCurrentTask.cancel
was using the normal rutime func, which the builtin would just end up
calling anyway.
I cna't see a reason to keep the builtin path, so let's remove this dead
code.
**Explanation**:
Implementation of `Continuation` as proposed in upcoming SE proposal:
https://github.com/swiftlang/swift-evolution/pull/3246
This is a ~Copyable Continuation with much stronger safety guarantees
and no runtime overhead. Refer to proposal for details.
Initial work by @fabianfett.
**Scope**: Adds a new continuation type.
**Risk**: Low, adds new type, allows `~Copyable` into existing builtin
-- I believe this change should be safe (?)
**Testing**: Added lots of tests covering problems this aims to prevent.
**Issues**:
resolves rdar://174826360
Somewhat relevant to rdar://139975911
Co-authored-by: Fabian Fett <fabianfett@apple.com>
Opaque return types are special type declarations that have it
own nested generic signature. Thus, given this:
```
protocol P<A> { associatedtype A: ~Copyable }
func f<T: ~Copyable>() -> some P<T> {}
```
The generic signature for f is <T where T Escapable>, and
for the opaque return type, its nested signature ends up as
```
<X where X: P, X.A == T>
```
With SE-503, we will now also expand a default for the suppressed
primary associated type, so the signature after expansion becomes
```
<X where X: P, X.A == T, X.A: Copyable>
```
It would be smarter to effectively have this rule
```
X.A == T, T: ~Copyable
----------------------
X.A: ~Copyable
```
where we infer the inverse on X.A to cancel-out the
expanded default X.A: Copyable. We already do this for
two in-scope type parameters, and it would be better if
we did it if one side was out-of-scope, but that would
be source-breaking to do in general.
In the case of opaque return types, the fact that
it has a nested generic signature seems more an
artifact of the implementation. There also is little
risk of source break, as the only kinds of same-type
requirements that can appear are from parameterized
protocol type.
The experimental suppressed associated types prior to
SE-503 wouldn't be broken by this change, as they do
not infer defaults that need suppression, and we only
filter-out requirements from defaults expansion, rather
than explicitly-written ones.
rdar://175500824
There's a need for more control over how default requirements
for conformance to Copyable/Escapable are expanded, and
subsequently how inverses are applied or inferred to cancel-out
those defaults.
The pattern of `/*applyInverses*/BOOL` is insufficient, so this
is a refactoring to grow that into a proper type that carries
an option that can be used in some future scenario about inferring
inverses for opaque return types.
This eliminates the need for unsafe addressors. It will replace unsafeAddress in
the UnsafePointer subscript and the Span subscript.
This is needed to support Span<~E>.
rdar://175382153 (Add Builtin.borrowAt: allows borrowing in-memory values)
I can't quite enable modeling their stack effects in this patch because
SILGen generates improperly-nested allocations; that'll be fixed in a
follow-up.
This is a follow up from the "async" `deinit` work, which will allow us
to guarantee cleanup code to run in deinitializers, even if they need to
call asynchronous code, and even if they may be run in a task that was
cancelled: by "shielding" it from cancellation.
This is incomplete, the child handling needs some more love.
SE proposal: https://github.com/swiftlang/swift-evolution/pull/3037/
Since after address lowering, `Borrow` can remain loadable with a known-
layout address-only referent, we need instructions that handle three
forms:
- borrow and referent are both loadable values
- borrow is a value, but referent is address-only
- borrow and referent are both address-only
This adds initial support for differentiation of functions that may produce `Error` result.
Essentially we wrap the pullback into `Optional` and emit a diamond-shape control flow pattern depending on whether the pullback value is available or not. VJP emission was modified to accommodate for this. In addition to this, some additional tricks are required as `try_apply` result is not available in the instruction parent block, it is available in normal successor basic block.
As a result we can now:
- differentiate an active `try_apply` result (that would be produced from `do ... try .. catch` constructions)
- `try_apply` when error result is unreachable (usually `try!` and similar source code constructs)
- Support (some) throwing functions with builtin differentiation operators. stdlib change will follow. Though we cannot support typed throws here (yet)
- Correctly propagate error types during currying around differentiable functions as well as type-checking for `@derivative(of:)` attribute, so we can register custom derivatives for functions producing error result
- Added custom derivative for `Optional.??` operator (note that support here is not yet complete as we cannot differentiate through autoclosures, so `x ?? y` works only if `y` is not active, e.g. a constant value).
Some fixes here and there
Before this patch we referred to builtin names in SILGenBuiltin using raw c
strings. This can lead to potential spelling mistakes yielding bugs. Rather than
doing this, I stole a technique that we use in other parts of the compiler:
constexpr StringLiteral generation using CPP macros. Specifically, I defined in
Builtins.h a new namespace called BuiltinNames and inside of BuiltinNames I used
CPP macros to define a StringLiteral for each Builtin. Thus one can get the
appropriate name for a Builtin by writing:
```
BuiltinNames::Sizeof
```
instead of writing "Sizeof". I also cleaned up the code a little by adding for
functions that take identifiers an additional overload that takes a StringRef
and converts the StringRef to an identifier internally. This just eliminates
unnecessary code from call sites by moving them into the callee.
This is necessary because we need to model its stack-allocation
behavior, although I'm not yet doing that in this patch because
StackNesting first needs to be taught to not try to move the
deallocation.
I'm not convinced that `async let` *should* be doing a stack allocation,
but it undoubtedly *is* doing a stack allocation, and until we have an
alternative to that, we will need to model it properly.
Builtin.FixedArray was introduced as the first generic builtin type, with
special case handling in all the various recursive visitors. Introduce
a base class, and move the handling to that base class, so it is easier
to introduce other generic builtins in the future.
This is currently not wired up to anything. I am going to wire it up in
subsequent commits.
The reason why we are introducing this new Builtin type is to represent that we
are going to start stealing bits from the protocol witness table pointer of the
Optional<any Actor> that this type is bitwise compatible with. The type will
ensure that this value is only used in places where we know that it will be
properly masked out giving us certainty that this value will not be used in any
manner without it first being bit cleared and transformed back to Optional<any
Actor>.
This is an NFC change. The idea is that this will make it easier to add new
BuiltinTypeKinds. I missed this code when adding Builtin.ImplicitIsolationActor.
By adding a covered switch, we can make sure this code is updated in the
future.
Ideally we'd be able to use the llvm interleave2 and deinterleave2
intrinsics instead of adding these, but deinterleave currently isn't
available from Swift, and even if you hack that in, the codegen from
LLVM is worse than what shufflevector produces for both x86 and arm. So
in the medium-term we'll use these builtins, and hope to remove them in
favor of [de]interleave2 at some future point.
It is like `zeroInitializer`, but does not actually initialize the memory.
It only indicates to mandatory passes that the memory is going to be initialized.
The builtin’s current is signature is:
```
(Any.Type, Any.Type) -> Bool
```
This needs to be changed to this:
```
(any (~Copyable & ~Escapable).Type, any (~Copyable & ~Escapable).Type) -> Bool
```
This requires a bit of support work in AST synthesis.
rdar://145707064
Co-authored-by: Alejandro Alonso <alejandro_alonso@apple.com>