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 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
@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.
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.
To summarize the theory based on
`validation-test/Evolution/test_protocol_add_reparented.swift`:
1. Two extensions on MultiParent share the mangled name
$s23protocol_add_reparented11MultiParentPAAEMXE for their context descriptor
2. The first extension to be emitted creates a GlobalVariable with type
TypeContextDescriptorTy (forward decl)
3. The second extension finds it in getAddrOfSharedContextDescriptor via
Module.getGlobalVariable() and inserts the same pointer in GlobalVars
4. When the first extension's descriptor gets defined, getAddrOfLLVMVariable
creates a new GlobalVariable and erases the old one.
5. The second extension's GlobalVars entry is now a dangling pointer, as the
act of defining it for the first extension definition didn't update the map.
This patch does seem to fix the dangling pointer, though there is probably
a better way to fix the underlying bad ordering of events.
Support for existentials in Embedded Swift has been available for a
little while now and appears to be solid. Remove the ability to disable
them (via `-disable-experimental-feature EmbeddedExistentials`), both
because it simplifies the code and because it's an ABI break to
disable the feature.
When building the `OSLog` module, look for a variable named
`osLogStringSectionName`. It must have a string literal as its
initializer, which provides the section name where the log strings
should be emitted. The `OSLog` module should contain something like
this:
let osLogStringSectionName = "__TEXT,__logit"
When not present, the compiler will default to
`__TEXT,__oslogstring,cstring_literals`, which was previously the
hardcoded section name. Now, OSLog can customize the name.
Implements rdar://171571056
We don't need to export the type metadata address point alias in clients that
lazily emit other module's type metadata. There will be an exported
metadata symbol in the originating module for that purpose.
Instead, satisfy any local uses of the metadata address point uses by its
underlying address computation.
This is to workaround a bug where LLVM generates the wrong assembly for
weak aliases that point to an offset of another symbol.
```
@"$e1C7MyClassCySiGN" = weak_odr hidden alias %swift.type, getelementptr
inbounds (<{ ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }>,
ptr @"$e1C7MyClassCySiGMf", i32 0, i32 1)
```
Generates:
```
.weak_reference _$e1C7MyClassCySiGN
.private_extern _$e1C7MyClassCySiGN
.alt_entry _$e1C7MyClassCySiGN
_$e1C7MyClassCySiGN = _$e1C7MyClassCySiGMf+8
```
Instead of
```
.weak_definition _$e1C7MyClassCySiGN
.private_extern _$e1C7MyClassCySiGN
.alt_entry _$e1C7MyClassCySiGN
_$e1C7MyClassCySiGN = _$e1C7MyClassCySiGMf+8
```
Leading for "weak"ness to be ignored and duplicate type medata symbol linkage
errors.
rdar://169573918
rdar://163631865
Under certain circumstances the same symbol can be used for different implementations of the forwarders.
The forwarders themselves are already emitted with "internal" LLVM linkage, but some particularities in
the mapping from SILLinkage to LLVM linkage caused async function pointers to partial apply forwarders
to be emitted with linkonce_odr instead, which caused the wrong forwarder to be called at runtime, causing
unexpected behavior and crashes.
We cannot use 'static' linkage for something that points into the
ASTContext, because there might be more than one ASTContext in a
single process.
Also, fix the spelling mistake in a related function name.
We currently disallow these by deleting them in the `swift` namespace.
This approach has several loopholes, all of which ultimately work
because we happen to define specializations of `simplify_type` for
`swift::Type`:
* `llvm::isa/cast/dyn_cast`. The deleted partial specializations will
not be selected because they are not defined in the `llvm` namespace.
* The argument is a non-const `Type`. The deleted function templates
will not be selected because they all accept a `const Type &`, and
there is a better `Y &Val` partial specialization in LLVM.
* Other casting function templates such as `isa_and_nonull` and
`cast_if_present` are not deleted.
Eliminate these loopholes by instead triggering a static assertion
failure with a helpful message upon instantiation of `CastInfo` for
`swift::Type`.
With multi-threaded IRGen, the global variables associated with "once"
initialization tokens were not getting colocated with their actual
global variables, which caused the initialization code to get split
across different files. This issue manifest as autolinking errors in
some projects.
Fixes rdar://162400654.
When generating dead stub methods for vtable entries, we should not
attach COMDATs to their definitions. This is because such stubs may be
referenced only through aliases, and the presence of a COMDAT on the
stub definition would cause the aliased symbol, we want to keep, to be
discarded from the symbol table when other object files also have a
dead stub method.
Given the following two object files generated:
```mermaid
graph TD
subgraph O0[A.swift.o]
subgraph C0[COMDAT Group swift_dead_method_stub]
D0_0["[Def] swift_dead_method_stub"]
end
S0_0["[Symbol] swift_dead_method_stub"] --> D0_0
S1["[Symbol] C1.dead"] --alias--> D0_0
end
subgraph O1[B.swift.o]
subgraph C1[COMDAT Group swift_dead_method_stub]
D0_1["[Def] swift_dead_method_stub"]
end
S0_1["[Symbol] swift_dead_method_stub"] --> D0_1
S2["[Symbol] C2.beef"] --alias--> D0_1
end
```
When linking these two object files, the linker will pick one of the
COMDAT groups of `swift_dead_method_stub`. The other COMDAT group will be
discarded, along with all symbols aliased to the discarded definition,
even though those aliased symbols (`C1.dead` and `C2.beef`) are the
ones we want to keep to construct vtables.
This change stops attaching COMDATs to dead stub method definitions.
This effectively only affects WebAssembly targets because MachO's
`supportsCOMDAT` returns false, and COFF targets don't use
`linkonce_odr` for dead stub methods.
The COMDAT was added in 7e8f782457
Removes the underscored prefixes from the @_section and @_used attributes, making them public as @section and @used respectively. The SymbolLinkageMarkers experimental feature has been removed as these attributes are now part of the standard language. Implemented expression syntactic checking rules per SE-0492.
Major parts:
- Renamed @_section to @section and @_used to @used
- Removed the SymbolLinkageMarkers experimental feature
- Added parsing support for the old underscored names with deprecation warnings
- Updated all tests and examples to use the new attribute names
- Added syntactic validation for @section to align with SE-0492 (reusing the legality checker by @artemcm)
- Changed @DebugDescription macro to explicitly use a tuple type instead of type inferring it, to comply with the expression syntax rules
- Added a testcase for the various allowed and disallowed syntactic forms, `test/ConstValues/SectionSyntactic.swift`.
IRGen introduces the symbol _swift_dead_method_stub for dead vtable
entries to point to. This symbol was given internal linkage, which
would result in multiply-defined symbols when combined with Embedded
Swift's use of aggressive CMO. Switch to linkonce_odr hidden linkage
so multiple versions of this symbol can be coalesced by the linker
(and dropped if not needed).
Fixes rdar://162392119.
The intent for `@inline(always)` is to act as an optimization control.
The user can rely on inlining to happen or the compiler will emit an error
message.
Because function values can be dynamic (closures, protocol/class lookup)
this guarantee can only be upheld for direct function references.
In cases where the optimizer can resolve dynamic function values the
attribute shall be respected.
rdar://148608854
Lazy emission of SIL global variables caused us to go through the
creation of two different LLVM struct types for the same
initialization, tripping an assertion in LLVM. Cache it along with
other information about the static-initialized object rather than
rebuilding it.
Also fix the lazy_globals test to account for the laziness,
generalizing it to also run on arm64 so I won't miss it locally.
Delay the emission of SIL global variables that aren't externally
visible until they are actually used. This is the same lazy emission
approach that we use for a number of other entities, such as SIL
functions.
Part of rdar://158363967.