Commit Graph

45 Commits

Author SHA1 Message Date
Evan Wilde
f3ff561c6f [NFC] add llvm namespace to Optional and None
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.
2023-06-27 09:03:52 -07:00
Arnold Schwaighofer
d810b0f7e4 IRGen: Pass the elementType of pointers through to operations
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`.
2022-10-03 15:27:12 -07:00
Josh Soref
9fa14ca215 Spelling irgen (#42470)
* spelling: abstractable

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: across

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: clazz

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: command

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: components

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: current

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: declared

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: discrimination

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: entities

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: except

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: existential

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: generic

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: initialization

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: initialize

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: inserted

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: instantiate

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: instantiation

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: interfere

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: interferes

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: intrinsic

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: metadata

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: might

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: multiple

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: necessary

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: objective

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: occurrences

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: outlined

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: parameters

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: payload

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: rearchitecting

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: replaceable

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: reverse

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: rewritable

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: shareably

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: specializations

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: speedup

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: template

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: that

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: the

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: transferred

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: uninitialized

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: witness

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

Co-authored-by: Josh Soref <jsoref@users.noreply.github.com>
2022-04-21 14:02:03 -07:00
Robert Widmann
f694bf585b Plumb GenericSignature of SIL Function Through IRGen 2022-03-08 03:09:19 -08:00
John McCall
58fe89f359 [NFC] Split up the "special convention" for runtime async functions
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.
2022-02-15 04:12:05 -05:00
Saleem Abdulrasool
19e2664139 Merge pull request #40292 from compnerd/constantinople
IRGen: do not mark AFP as const
2021-12-05 10:18:36 -08:00
Pavel Yaskevich
38b2b650c9 [IRGen] NFC: Remove outdated comment about number of async parameters 2021-11-29 16:15:53 -08:00
Saleem Abdulrasool
64d2d39f32 IRGen: do not mark AFP as const
We were not marking the async function pointer as constant but adding it
to the `.rdata` section which the Windows linker helped identify as a
problem: we were adding data with "rw" to a section that is expected to
be "rd".  Marking the data as constant results in error propagation
breaking (presumably due to failure to materialize parameters properly
as bindiff'ing the Concurrency library indicates that the functions are
nearly identical with some argument loads elided).  This repairs the
emission of read/write data into the readonly section.
2021-11-25 11:00:35 -08:00
Saleem Abdulrasool
68bc33fed3 IRGen: initial pass to support async inheritance on Windows
With PE/COFF, one cannot reference a data symbol directly across the
binary module boundary.  Instead, the reference must be indirected
through the Import Address Table (IAT) to allow for position
independence.

When generating a reference to a AsyncFunctionPointer ({i8*, i32}), we
tag the pointer as being indirected by tagging bit 1 (with the
assumption that native alignment will ensure 4/8 byte alignment, freeing
the bottom 2 bits at least for bit-packing).  We tweak the
v-table/witness table emission such that all references to the
AsyncFunctionPointer are replaced with the linker synthetic import
symbol with the bit packing:

~~~
.quad __imp_$s1L1CC1yyYaKFTu+1
~~~

rather than

~~~
.quad $s1L1CC1yyYaKFTu
~~~

Upon access of the async function pointer reference, we open-code the
check for the following:

~~~
pointer = (pointer & 1) ? *(void **)(pointer & ~1) : pointer;
~~~

Thanks to @DougGregor for the discussion and the suggestion for the
pointer tagging.  Thanks to @aschwaighofer for pointers to the code that
I had missed.  Also, thanks to @SeanROlszewski for the original code
sample that led to the reduced test case.

Fixes: SR-15399
2021-11-01 11:23:51 -07:00
Arnold Schwaighofer
8cdde7a618 IRGen: Define and use an earliest insertion point
This is to deal with the fact that LLVM's coroutine can't handle instructions
with side-effects well that are inserted before the coro.begin.

rdar://81113950
2021-07-29 09:53:46 -07:00
Arnold Schwaighofer
10e3d2e3af Change _wait(_throwing) ABIs to reduce code size
Changes the task, taskGroup, asyncLet wait funtion call ABIs.

To reduce code size pass the context parameters and resumption function
as arguments to the wait function.

This means that the suspend point does not need to store parent context
and resumption to the suspend point's context.

```
  void swift_task_future_wait_throwing(
    OpaqueValue * result,
    SWIFT_ASYNC_CONTEXT AsyncContext *callerContext,
    AsyncTask *task,
    ThrowingTaskFutureWaitContinuationFunction *resume,
    AsyncContext *callContext);
```

The runtime passes the caller context to the resume entry point saving
the load of the parent context in the resumption function.

This patch adds a `Metadata *` field to `GroupImpl`. The await entry
pointer no longer pass the metadata pointer and there is a path through
the runtime where the task future is no longer available.
2021-06-08 10:41:26 -07:00
Nate Chandler
d3e0e7af07 [ptrauth] Signed AsyncFunctionPointers as data.
Previously, AsyncFunctionPointer constants were signed as code.  That
was incorrect considering that these constants are in fact data.  Here,
that is fixed.

rdar://76118522
2021-04-05 18:24:41 -07:00
Arnold Schwaighofer
3bdd5cb99a IRGen: async error ABI
Throwing functions pass the error result in `swiftself` to the resume
partial function.
Therefore, `() async -> ()` to `() async throws -> ()` is not ABI compatible.

TODO: go through remaining failing IRGen async tests and replace the
illegal convert_functions.
2021-03-17 17:17:12 -07:00
Arnold Schwaighofer
f75fbb7594 IRGen: Async ABI passing parameter and results directly
The error is still passed in the async context. I will fix this in a
follow-up.
2021-03-17 07:41:01 -07:00
Arnold Schwaighofer
8c5fc073fd [IRGen] Use coro.end.async to return from an async function
The `coro.end.async` intrinsic allow specifying a function that is to be
tail-called as the last thing before returning.

LLVM lowering will inline the `must-tail-call` function argument to
`coro.end.async`. This `must-tail-call` function can contain a
`musttail` call.

```
define @my_must_tail_call_func(void (*)(i64) %fnptr, i64 %args) {
  musttail call void %fnptr(i64 %args)
  ret void
}

define @async_func() {
  ...
  coro.end.async(..., @my_must_tail_call_func, %return_continuation, i64 %args)
  unreachable
}
```
2021-03-10 10:15:27 -08:00
John McCall
2012195cd5 Alter the runtime interface for awaiting futures and task groups.
First, just call an async -> T function instead of forcing the caller
to piece together which case we're in and perform its own copy.  This
ensures that the task is actually kept alive properly.

Second, now that we no longer implicitly depend on the waiting tasks
being run synchronously, go ahead and schedule them to run on the
global executor.

This solves some problems which were blocking the work on TLS-ifying
the task/executor state.
2021-02-21 23:48:13 -05:00
nate-chandler
de63a23e77 Merge pull request #35603 from nate-chandler/concurrency/irgen/rdar71378532
[Async CC] Make error indirect.
2021-02-16 07:39:14 -08:00
Slava Pestov
72e1f02ae2 IRGen: Fix async dispatch thunk emission with loadable return value
Fixes <rdar://problem/74246091>.
2021-02-12 14:06:07 -05:00
Nate Chandler
e2a8abc9e5 [Async CC] Make error indirect.
Previously, the error stored in the async context was of type SwiftError
*.  In order to enable the context to be callee released, make it
indirect and change its type to SwiftError **.

rdar://71378532
2021-02-11 11:34:47 -08:00
Slava Pestov
adc92e95d2 IRGen: Fix preservation of error result in async dispatch thunks 2021-01-30 00:05:57 -05:00
Slava Pestov
9813e94dc8 IRGen: Use CallEmission to emit dispatch thunks
This increases the level of abstraction a bit and makes it easier to stage
in the requisite support for async method calls. For now, I've kept the
existing, incomplete logic for those.

Part of rdar://problem/73625623.
2021-01-28 00:05:40 -05:00
Slava Pestov
c79de40225 IRGen: Emit async function pointers for resilient class and protocol dispatch thunks
This adds new kinds of link entities corresponding to the three
dispatch thunk link entity kinds:

- DispatchThunkAsyncFunctionPointer
- DispatchThunkInitializerAsyncFunctionPointer
- DispatchThunkAllocatorAsyncFunctionPointer
2021-01-27 15:21:22 -05:00
Slava Pestov
8440a8226f IRGen: More refactoring in preparation for emitting async function pointers for dispatch thunks 2021-01-27 13:50:34 -05:00
Erik Eckstein
bf2be9eb5d [concurrency] IRGen: update task/executor/context on every suspend point
For this, store those 3 values on the stack at function entry and update them with the return values of coro_suspend_async intrinsic calls.

This fixes a correctness issue, because the executor may be different after a resume.
It also is more efficient, because this means that the 3 values don't have to preserved in the context over a suspension point.
2020-12-01 15:19:39 +01:00
Nate Chandler
e06d316fe7 [Async CC] Find wtable in async context in thunk.
Previously, when looking up a protocol method, the witness table was
always exepcted to be the final argument passed to the function.

That is true for sync protocol witnesses but not for async witnesses.
In the async case, the witness table is embedded in the async context.

Here, the witness table is dug out of the async context.

rdar://problem/71491604
2020-11-17 11:23:37 -08:00
Nate Chandler
e27647244d [AsyncCC] Resolve metadata from class instances.
Metadata for an instance of a type is resolved by extracting it from an
instance of the class.  When doing method lookup for an instance method
of a resilient class, the lowered self value was being obtained from the
list of arguments directly by indexing.  That does not apply to async
functions where self is embedded within the async context.  Here, the
self parameter is extracted from the async context so that the metadata
can in turn be extracted from it.

rdar://problem/71260862
2020-11-14 15:15:12 -08:00
Nate Chandler
2d21932672 [Async CC] Add constant "pointer" for async func.
An AsyncFunctionPointer, defined in Task.h, is a struct consisting of
two i32s: (1) the relative address of the async function and (2) the
size of the async context to be allocated when calling that function.

Here, such structs are emitted for every async SILFunction that is
emitted.
2020-11-12 18:20:10 -08:00
Nate Chandler
e23cc54145 [IRGen] Skip reemitting fields referenced by type context descriptor.
When reemitting a type context descriptor, several fields
- method lookup function
- dispatch thunk
- nonoverride method descriptor
were previously being reemitted.

In a couple of earlier commits, that behavior was altered to delete the
fields before reemitting them.

  3ad2777a68 [IRGen] Erase nonoverride descriptor on emission.
  c25c180c08 [IRGen] Erase thunks before emission.

Here, the behavior is changed to simply exit early when these fields are
being reemitted.  Also an assertion is added that these fields are
redefined only when reemitting the type context descriptor.
2020-08-15 09:54:54 -07:00
Nate Chandler
c25c180c08 [IRGen] Erase thunks before emission.
Previously, a call to emitMethodLookupFunction or emitDispatchThunk
would always simply emit a function, even if it had previously been
emitted.  That was a problem since these emissions are triggered by
emitting class type context descriptors which can now be lazily
reemitted upon encountering prespecialized metadata.

Here, that behavior is changed to delete the old body, if any, before
emitting the body again.
2020-08-13 17:35:21 -07:00
Joe Groff
3a9440a379 IRGen: Elide nonoverridden entries from public resilient vtables.
A formally virtual method still needs to provide the ABI of an overridable
method, including a dispatch thunk, method descriptor, and support in the
method lookup function for the class to handle `super.` calls from clients.
2020-07-23 20:40:49 -07:00
Arnold Schwaighofer
147144baa6 SIL: Thread type expansion context through to function convention apis
This became necessary after recent function type changes that keep
substituted generic function types abstract even after substitution to
correctly handle automatic opaque result type substitution.

Instead of performing the opaque result type substitution as part of
substituting the generic args the underlying type will now be reified as
part of looking at the parameter/return types which happens as part of
the function convention apis.

rdar://62560867
2020-05-04 13:53:30 -07:00
Arnold Schwaighofer
2ea1c5cc41 Use IGM.getMaximalTypeExpansionContext() in more places 2019-11-11 14:21:52 -08:00
Arnold Schwaighofer
4cba76309f IRGen: Add TypeExpansionContext to IRGen 2019-11-11 14:21:52 -08:00
Joe Groff
03c7919b4a SIL: Add fields to SILFunctionType for substituted function types.
https://forums.swift.org/t/improving-the-representation-of-polymorphic-interfaces-in-sil-with-substituted-function-types/29711

This prepares SIL to be able to more accurately preserve the calling convention of
polymorphic generic interfaces by letting the type system represent "substituted function types".
We add a couple of fields to SILFunctionType to support this:

- A substitution map, accessed by `getSubstitutions()`, which maps the generic signature
  of the function to its concrete implementation. This will allow, for instance, a protocol
  witness for a requirement of type `<Self: P> (Self, ...) -> ...` for a concrete conforming
  type `Foo` to express its type as `<Self: P> (Self, ...) -> ... for <Foo>`, preserving the relation
  to the protocol interface without relying on the pile of hacks that is the `witness_method`
  protocol.

- A bool for whether the generic signature of the function is "implied" by the substitutions.
  If true, the generic signature isn't really part of the calling convention of the function.
  This will allow closure types to distinguish a closure being passed to a generic function, like
  `<T, U> in (*T, *U) -> T for <Int, String>`, from the concrete type `(*Int, *String) -> Int`,
  which will make it easier for us to differentiate the representation of those as types, for
  instance by giving them different pointer authentication discriminators to harden arm64e
  code.

This patch is currently NFC, it just introduces the new APIs and takes a first pass at updating
code to use them. Much more work will need to be done once we start exercising these new
fields.

This does bifurcate some existing APIs:

- SILFunctionType now has two accessors to get its generic signature.
  `getSubstGenericSignature` gets the generic signature that is used to apply its
  substitution map, if any. `getInvocationGenericSignature` gets the generic signature
  used to invoke the function at apply sites. These differ if the generic signature is
  implied.
- SILParameterInfo and SILResultInfo values carry the unsubstituted types of the parameters
  and results of the function. They now have two APIs to get that type. `getInterfaceType`
  returns the unsubstituted type of the generic interface, and
  `getArgumentType`/`getReturnValueType` produce the substituted type that is used at
  apply sites.
2019-10-25 13:38:51 -07:00
Doug Gregor
602b38e444 [IRGen] Centralize alignment/default type information in LinkEntity.
Simplify calls to getAddrOfLLVMVariableOrGOTEquivalent() and
getAddrOfLLVMVariable() by moving the computation of the alignment and
default type into LinkEntity.

Co-authored-by: Joe Groff <jgroff@apple.com>
2018-10-23 09:57:03 -07:00
swift-ci
7ef1696450 Merge pull request #19210 from DougGregor/keypath-protocol-overrides 2018-09-10 12:28:29 -07:00
Doug Gregor
c6e9b24425 [IRGen] Adjust keypath component id for overriding witness methods. 2018-09-10 10:45:14 -07:00
Slava Pestov
9347a072e5 IRGen: Emit method lookup function 2018-09-07 21:50:58 -07:00
Slava Pestov
100679aa1e IRGen: Use a method descriptor to identify methods where possible
This eliminates the 'non-resilient class' case here entirely since
all class methods have method descriptors.
2018-09-07 12:15:24 -07:00
Slava Pestov
44c4497ac5 IRGen/Runtime: Protocol requirement descriptors don't need to reference the dispatch thunk 2018-08-31 00:16:22 -07:00
Slava Pestov
771eacb4df IRGen: Emit method descriptors 2018-08-31 00:20:39 -06:00
Slava Pestov
b7ff05d036 IRGen: Fix handling of dispatch thunks
Tests fail with the next patch.
2018-03-23 18:59:07 -06:00
John McCall
aaa40ee82b Move metadata-accessing IRGen out of GenMeta. NFC.
Abstract type/heap metadata access goes into MetadataRequest.
Metadata access starting from a heap object goes into GenHeap.
Accessing various components of class metadata goes into GenClass
or MetadataLayout.
2018-03-18 23:53:11 -04:00
Slava Pestov
9b0f6fca53 IRGen: Emit class dispatch thunks in IRGen instead of SILGen
This allows us to re-use the same code for emitting protocol dispatch
thunks.
2018-01-15 22:38:16 -08:00
Slava Pestov
698881d5c6 IRGen: Protocol dispatch thunks
We want to be able to re-order existing protocol requirements
and add new protocol requirements with default implementations.

Enable this by wrapping the witness table lookup inside a
thunk and calling the thunk, instead of open-coding the
witness table lookup directly in client code.
2018-01-10 13:54:21 -08:00