Adding a few more updates to places where the ABI Alignment functions
changed. `getABITypeAlignment` was replaced with `getABITypeAlign`,
which returns an `llvm::Align` instead of an unsigned int.
LLVM deprecated, renamed, and removed a bunch of APIs. This patch
contains a lot of the changes needed to deal with that.
The SetVector type changed the template parameters.
APInt updated multiple names, countPopulation became popcount,
getAllOnesValue became getAllOnes, getNullValue became getZero, etc...
Clang type nullability check stopped taking a clang AST context.
The LLVM IRGen Function type stopped exposing basic block list directly,
but gained enough API surface that the translation isn't too bad.
(GenControl.cpp, LLVMMergeFunctions.cpp)
llvm::Optional had a transform function. That was being used in a couple
of places, so I've added a new implementation under STLExtras that
transforms valid optionals, otherwise it returns nullopt.
Arguments that have been loaded due to underlying method conversion
have to be destroyed after the call otherwise they are going to leak.
Resolves: https://github.com/apple/swift/issues/65853
Resolves: rdar://109207043
- SILPackType carries whether the elements are stored directly
in the pack, which we're not currently using in the lowering,
but it's probably something we'll want in the final ABI.
Having this also makes it clear that we're doing the right
thing with substitution and element lowering. I also toyed
with making this a scalar type, which made it necessary in
various places, although eventually I pulled back to the
design where we always use packs as addresses.
- Pack boundaries are a core ABI concept, so the lowering has
to wrap parameter pack expansions up as packs. There are huge
unimplemented holes here where the abstraction pattern will
need to tell us how many elements to gather into the pack,
but a naive approach is good enough to get things off the
ground.
- Pack conventions are related to the existing parameter and
result conventions, but they're different on enough grounds
that they deserve to be separated.
When using opaque pointers we can no longer depend on the LLVM IR type
to perform the computation. Instead compute the number while we are
building a signature.
In preparation for moving to llvm's opaque pointer representation
replace getPointerElementType and CreateCall/CreateLoad/Store uses that
dependent on the address operand's pointer element type.
This means an `Address` carries the element type and we use
`FunctionPointer` in more places or read the function type off the
`llvm::Function`.
Since invocation decoder is no longer required to be a class-bound
type, accessors have to be made generic over actual type of decoder.
Each accessor still knows what is the expected type of a decoder is
(based on the distributed actor it's associated with), so it still
does direct method calls but it has to load data decoder instance
first iff the decoder is a class.
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.
The witness table is an array of pointers - `void **`,
which means that the list of the witnesses has type of `void ***`.
Instead of using result of `emitAddressAtOffset` accessor
should set the correct type for the list, which is `void ***`
and emit bit a lot for each of the witness table slots.
Resolves: rdar://87568630
Resolves: rdar://88340451
`decodeNextArgument` requires (at least) that argument type conform
to a serialization requirement, witness table(s) for all protocol
requirements have to be lookup up by accessor to form correct
`decodeNextArgument` invocation.
Given a distributed thunk, find and cache a pointer to suitable
argument decoder method together with its type. The decoder is
a concrete type associated with actor via `InvocationDecoder`
associated type on `DistributedActorSystem` which should have a
`decodeNextArgument` method.
This is the case of e.g. `Array<T>` where argument is `Array<Int>`
we need to compute offset/size based on argument metadata but load
the argument using parameter type information.
To load generic argument value, we need to retrieve argument type
from the argument types buffer, based on that load value size and
alignment, and only then fetch actual value from the argument buffer
as `swift.opaque *`.
* [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
`getPointerToMethod()` should acoount for the fact that distributed
thunk is an async function, so direct pointer should be to "async
pointer" information instead of SIL function.
Instead of trying to return result from distributed thunk directly,
modify accessor to store result into the caller-provided buffer.
Doing so helps us avoid boxing the result into `Any`.