Just like we do with SILFunction, allow a code generation model to be
specified on a SILGlobalVariable and maintain that through the printed
and serialized forms.
Declarations that are potentially used externally, including those
exposed to foreign languages (e.g., via `@c`), placed in a specific
section (`@section`), or explicitly marked used (`@used`) are
generally eagerly emitted in IR. Embedded Swift was overriding this in
a partial manner, applying specific linkage rules to them to force
them to have unique definitions (regardless of the code generation
model) and then overriding the behavior later on when it came to lazy
emission.
Remove the special cases for Embedded. These declarations will now
follow the same linkage rules as all other declarations, greatly
simplifying the "is non-unique definition" check, and will be
considered as being emitted non-lazily.
The default code generation model for Embedded Swift is "inlinable".
DeferredCodeGen made the default code generation model
"implementation", and there was no spelling for "interface".
Introduce the experimental feature CodeGenerationModel=<model>, which
can be any of those three options. The default remains "inlinable", but
one can now specify "implementation" (which keeps most everything in
SIL) or "interface" (which only keeps the generic things in SIL). The
"interface" mode is more like non-embedded Swift for non-generic
declarations, emitting them into the IR (only) but not SIL. Generic
declarations would remain in SIL.
Implements rdar://172433062.
The code generation model for a particular declaration or conformance
can be defined explicitly with `@export(interface)`,
`@export(implementation)`, or `@inlinable` (for declarations),
indicating where the definition will occur.
Embedded Swift also has some limitations on what can be emitted into
IR. For example, a generic function cannot be `@export(interface)`
because Embedded Swift does not support unspecialized generics.
Compute the effective code generation model based on what was
explicitly specified, the limitations of the model, and the default
code generation model for the given module, which defaults to
"inlinable" but can be made "implementation" by the DeferredCodeGen
feature. Use the effective code generation model for IR- and SIL-level
determinations of linkage and where to emit symbols.
[WIP] Start computing and using the "effective" code generation model
FIXUP linkage of the alias symbol
When using parallel whole module optimization (-num-threads N), we were
getting GOT entries for references to witness tables that show up in
another object file of the same module. These are not necessary and
were getting linked into NULL references, causing crashes later on.
The recent implementation of `@export(interface)` for type metadata and
protocol witness tables (pull request #88979) fixed this as a drive-by
improvement, eliminating the GOT entry and using a normal relocation.
Add a test to make sure it stays fixed.
Protocol conformances normally have shared linkage in Embedded Swift.
However, allow the use of @export(interface) on conformances (by way
of their enclosing nominal type or extension), which will emit the
witness tables for those conformances as strong symbols in the owning
module, and references to these symbols from other modules.
At the SIL level, ensure that witness tables always have shared linked
when building Embedded Swift. This is the correct starting point, to be
revised for @export(interface).
@export(interface) makes it so that Embedded Swift will emit a strong
definition of a symbol in its defining module, and use that symbol in
other modules. Extend this notion to non-generic types, where we will
emit a strong definition for the full type metadata, and let it be
referenced from other modules rather than the lazy, shared emission.
Implements rdar://176392354.
If the fix-it would remove a range that is followed by a newline and the
remaining text on the line is empty or all whitespace then remove the entire
line. This produces better results when a fix-it removes an attribute that is
written on a line by itself.
Use unreachable methods instead of abstract methods in the Embedded
concurrency library, so that the C++ compiler doesn't inject a
reference to __cxa_pure_virtual, which is in the C++ runtime.
Rather than always calling malloc/free, parameterize the StackAllocator
on the underlying global allocator. The default uses malloc/free, so
most uses of StackAllocator are unchanged by this refactoring.
In the embedded concurrency library, swap in an global allocator that
uses swift_slowAllloc/swift_slowDealloc instead, eliminating the
remaining malloc/free references so everything goes through the
platform abstraction layer. For now, don't change the non-embedded
concurrency library in the same manner.
Avoid more of the C standard library to reduce dependencies and code
size. This removes a bunch of code used to format nice fatal error
messages, reducing code size at some cost to debuggability. This is a
deliberate tradeoff in Embedded Swift.
We had to do a silly trick to avoid strlen, because LLVM likes to
pattern-match the loop and inject the standard library dependency,
which we do not want.
Fatal errors in the concurrency runtime used a mix of
swift_Concurrency_fatalError[v] and manual calls to abort(). Drop the
dependency on abort() by routing all true fatal errors through
swift_Concurrency_fatalErrorv and eventually to a new
`_swift_fatalError` C entrypoint defined in the Embedded Swift
runtime, which (optionally) prints and then (always) traps.
The concurrency library accounts for distributed actors, which
introduces some dependencies on metadata computations that we don't
want. Distributed actors are not supported in Embedded Swift, so
remove these functions to drop the external reference.
This function isn't used in the Embedded Concurrency library, and
refers to another logging function that isn't provided in the Embedded
Swift runtime.
Embedded Swift doesn't provide reporting to a debugger, which entails
system dependencies we don't model. Remove this functionality from the
Embedded Concurrency build.
Part of rdar://176300169.
This PR allows the use, in Embedded Swift, of the overloads of
`String.init(describing:)` that are constrained to specific protocols
(currently `CustomStringConvertible` and `TextOutputStreamable`). These
overloads can be fully supported in Embedded Swift as they do not rely
on runtime type inspection and just call through to protocol
requirements known at compile time.
- **Explanation**: Allows some uses of `String.init(describing:)` in
Embedded Swift.
- **Scope**: Embedded Swift, stringification
- **Issues**: rdar://139729101
- **Risk**: Low
- **Testing**: Existing CI coverage and new test file.
Inlinable code that uses `if #available` in the standard library
currently ends up referencing _stdlib_isOSVersionAtLeast. Avoid using
it in the floating point parsing code.
Fixes#88698 / rdar://175730290
The Embedded Swift dynamic casting logic was getting a bit tangled, and
used some heuristics for figuring out the existential representation
that didn't always work, e.g., with class-bound types.
Reimplement the entire thing using the same general approach that the
non-Embedded runtime uses, albeit simplified greatly because Embedded
Swift doesn't permit casting to existential types (only *from*
existential types). The new implementation correctly unwraps all levels
of existential, short-circuits where appropriate, and "takes" wherever
possible.
This change does require emitting some more metadata than we did
before, because it is necessary to handle the different existential
representations correctly. Previously, the compiler would pass a NULL
pointer as the "source" metadata to `swift_dynamicCast`, then try to
figure out what it was given by inspecting the source pointer. This is
insufficient for distinguishing the various existential representations
(opaque, class-bound, error) and relied on heuristics. Start passing
destination metadata to this function, just as we do in non-Embedded
Swift. This means we'll end up generating some more metadata for
existential types (like `any P`) that we wouldn't have before, but
it's still pay-per-use and they are relatively small. All of the other
metadata that can flow here will already have been created for other
reasons, e.g., because classes already have it in their vtable.
This also extends the metadata associated with existential types by one
more word (from 2 to 3). The new word is used to provide the
existential representation, which is needed for dynamic casting as
described above.
Teach swift_dynamicCast to repeatedly unwrap "any Error" existentials
before matching the concrete type.
Required to make rdar://175590869 work through AsyncStream.
Following the emission of metadata for tuple and function types, also
lazily emit (sparse) metadata for metatype and existential types. This
is needed when forming existential values.
Now that we have generalized existentials in Embedded Swift, we also
have all of the infrastructure for metatypes. They're lazily
constructed on an as-needed basis, but otherwise work the same way as
in non-Embedded Swift.
Fixes rdar://145706221.
Now that we have untyped throws support in Embedded Swift, remove the
special cases that trapped when a task (or anything built on it)
throws. Introduce some tests that ensure that we can throw errors
through a Task or "async let" and catch the error.
Fixes rdar://175590869.