So far, static arrays had to be put into a writable section, because the isa pointer and the (immortal) ref count field were initialized dynamically at the first use of such an array.
But with a new runtime library, which exports the symbols for the (immortal) ref count field and the isa pointer, it's possible to put the whole array into a read-only section. I.e. make it a constant global.
rdar://94185998
These instructions have the following attributes:
1. copyably_to_moveonlywrapper takes in a 'T' and maps it to a '@moveOnly
T'. This is semantically used when initializing a new moveOnly binding from a
copyable value. It semantically destroys its input @owned value and returns a
brand new independent @owned @moveOnly value. It also is used to convert a
trivial copyable value with type 'Trivial' into an owned non-trivial value of
type '@moveOnly Trivial'. If one thinks of '@moveOnly' as a monad, this is how
one injects a copyable value into the move only space.
2. moveonlywrapper_to_copyable takes in a '@moveOnly T' and produces a new 'T'
value. This is a 'forwarding' instruction where at parse time, we only allow for
one to choose it to be [owned] or [guaranteed].
* moveonlywrapper_to_copyable [owned] is used to signal the end of lifetime of
the '@moveOnly' wrapper. SILGen inserts these when ever a move only value has
its ownership passed to a situation where a copyable value is needed. Since it
is consuming, we know that the no implicit copy checker will ensure that if we
need a copy for it, the program will emit a diagnostic.
* moveonlywrapper_to_copyable [guaranteed] is used to pass a @moveOnly T value
as a copyable guaranteed parameter with type 'T' to a function. In the case of
using no-implicit-copy checking this is always fine since no-implicit-copy is a
local pattern. This would be an error when performing no escape
checking. Importantly, this instruction also is where in the case of an
@moveOnly trivial type, we convert from the non-trivial representation to the
trivial representation.
Some important notes:
1. In a forthcoming commit, I am going to rebase the no implicit copy checker on
top of these instructions. By using '@moveOnly' in the type system, we can
ensure that later in the SIL pipeline, we can have optimizations easily ignore
the code.
2. Be aware of is that due to SILGen only emitting '@moveOnly T' along immediate
accesses to the variable and always converts to a copyable representation when
calling other code, we can simply eliminate from the IR all moveonly-ness from
the IR using a lowering pass (that I am going to upstream). In the evil scheme
we are accomplishing here, we perform lowering of trivial values right after
ownership lowering and before diagnostics to simplify the pipeline.
On another note, I also fixed a few things in SILParsing around getASTType() vs
getRawASTType().
`findDbgValues` was moved from `llvm/Transforms/Utils/Local.h` into
`llvm/IR/DebugInfo.h` in llvm/llvm-project
0ebf9a8e34b6aeee520aa5dc6916a155c5789533. Include that header instead.
Not sure which LLVM commit added an `#undef` for `DEBUG_TYPE` in a header
transitively included by these files, but it doesn't seem uncommon
for headers to define and undefine their own `DEBUG_TYPE`.
Move `#define DEBUG_TYPE` after the includes to prevent it being
undefined.
`PointerType::getElementType` has been removed entirely as part of the
opaque pointers migration. Update to `getPointerElementType` for now
until we've also migrated.
This fixes the issues I was in my earlier PR about seeing with vars not getting
appropriate debug info when moved. Now we get the right debug info and in the
dwarf can see the two live ranges of our moved value as we hoped for.
NOTE: I disabled alloc stack hoisting on move_function_debuginfo.swift since it
can result in us eliminating debug info at -Onone when we merge alloc_stack. I
am preparing a separate patch that fixes that issue but hit a lldb problem. This
unblocks this PR from that change since they are not /actually/ related.
Reduces the number of _ContiguousArrayStorage metadata.
In order to support constant time bridging we do need to set the correct
metadata when we bridge to Objective-C. This is so that the type check
succeeds when bridging back from Objective-C to reuse the storage
instance rather than bridging the elements.
To support dynamically setting the `_ContiguousArrayStorage` element
type i needed to add support for optimizing `alloc_ref_dynamic`
throughout the optimizer.
Possible future improvements:
* Use different metadata such that we can disambiguate native Swift
classes during destruction -- allowing native release rather then unknown
release usage.
* Optimize the newly added semantic function
getContiguousArrayStorageType
rdar://86171143
The special convention currently means three things:
1. There is no async FP symbol for the function. Calls should go directly
to the function symbol, and an async context of fixed static size should be
allocated. This is mandatory for calling runtime-provided async functions.
2. The callee context should be allocated but not initialized. The main
context pointer passed should be the caller's context, and the continuation
function pointer and callee context should be passed as separate arguments.
The function will resume the continuation function pointer with the caller's
context. This is a micro-optimization appropriate for functions that are
expected to frequently return immediately; other functions shouldn't bother.
3. Generic arguments should be suppressed. This is a microoptimization for
certain specific runtime functions where we happen to know that the runtime
already stores the appropriate information internally. Other functions
probably don't want this.
Obviously, these different treatments should be split into different
predicates so that functions can opt in to different subsets of them.
I've also set the code up so that runtime functions can more easily
request a specific static async context size. Previously, it was a
confusingly embedded assumption that the static context size was always
exactly two pointers more than the header.
This is an instruction that I am going to use to drive some of the ownership
based dataflow optimizations that I am writing now. The instruction contains a
kind that allows one to know what type of checking is required and allows the
need to add a bunch of independent instructions for independent checkers. Each
checker is responsible for removing all of its own mark instructions. NOTE:
MarkMustCheckInst is only allowed in Raw SIL since once we are in Canonical SIL
we want to ensure that all such checking has already occurred.
* [Distributed] Implement func metadata and executeDistributedTarget
dont expose new entrypoints
able to get all the way to calling _execute
* [Distributed] reimplement distributed get type info impls
* [Distributed] comment out distributed_actor_remoteCall for now
* [Distributed] disable test on linux for now
Introduce a new instruction `dealloc_stack_ref ` and remove the `stack` flag from `dealloc_ref`.
The `dealloc_ref [stack]` was confusing, because all it does is to mark the deallocation of the stack space for a stack promoted object.
There are three major changes here:
1. The addition of "SILFunctionTypeRepresentation::CXXMethod".
2. C++ methods are imported with their members *last*. Then the arguments are switched when emitting the IR for an application of the function.
3. Clang decls are now marked as foreign witnesses.
These are all steps towards being able to have C++ protocol conformance.
Direct pointer to the accessor cannot be called at runtime,
so here is how everything is stored:
- For `distributed` and `async` functions -> async function pointer;
- For regular functions -> function pointer.
Uses a dedicated section in the binary to emit records about
functions that can be looked up by name at the runtime, and
then called through a fully-abstracted entry point whose
arguments can be constructed in code.
Instead of using the distributed method directly, let's always
call distributed thunk instead which is safe option because
actor could not be local (e.g. issue with routing) but only
distributed thunk would know that and take appropriate action.
This instruction is similar to a copy_addr except that it marks a move of an
address that has to be checked. In order to keep the memory lifetime verifier
happy, the semantics before the checker runs are the mark_unresolved_move_addr is
equivalent to copy_addr [init] (not copy_addr [take][init]).
The use of this instruction is that Mandatory Inlining converts builtin "move"
to a mark_unresolved_move_addr when inlining the function "_move" (the only
place said builtin is invoked).
This is then run through a special checker (that is later in this PR) that
either proves that the mark_unresolved_move_addr can actually be a move in which
case it converts it to copy_addr [take][init] or if it can not be a move, emit
an error and convert the instruction to a copy_addr [init]. After this is done
for all instructions, we loop back through again and emit an error on any
mark_unresolved_move_addr that were not processed earlier allowing for us to
know that we have completeness.
NOTE: The move kills checker for addresses is going to run after Mandatory
Inlining, but before predictable memory opts and friends.
Required for UnsafeRawPointer.withMemoryReboud(to:).
%out_token = rebind_memory %0 : $Builtin.RawPointer to %in_token
%0 must be of $Builtin.RawPointer type
%in_token represents a cached set of bound types from a prior memory state.
%out_token is an opaque $Builtin.Word representing the previously bound
types for this memory region.
This instruction's semantics are identical to ``bind_memory``, except
that the types to which memory will be bound, and the extent of the
memory region is unknown at compile time. Instead, the bound-types are
represented by a token that was produced by a prior memory binding
operation. ``%in_token`` must be the result of bind_memory or
The functions in llvm-project `AttributeList` have been
renamed/refactored to help remove uses of `AttributeList::*Index`.
Update to use these new functions where possible. There's one use of
`AttrIndex` remaining as `replaceAttributeTypeAtIndex` still takes the
index and there is no `param` equivalent. We could add one locally, but
presumably that will be added eventually.