LTO pipeline requires consistent `EnableSplitLTOUnit` and module summary
in regular full LTO bitcode, and clang enables `EnableSplitLTOUnit` and
emit regular lto module summary on non-ld64 platforms.
Therefore, swiftc has to emit them for the consistency with clang.
This has a few nice benefits:
1. The splitting happens after LLVM optimizations have run. This ensures that
LLVM will not join these blocks no matter what! The author of this commit has
found that in certain cases LLVM does this even at -Onone. By running this late,
we get the benefit we are looking for: working around the bad SelectionDAG
behavior.
2. This block splitting is just a workaround for the above mentioned unfortunate
SelectionDAG behavior. By doing this when we remove the workaround, we will not
have to update SIL level tests... instead we will just remove a small LLVM pass.
Some additional notes:
1. Only moved values will ever have llvm.dbg.addr emitted today, so we do not
have to worry about this impacting the rest of the language.
2. The pass's behavior is tested at the IR level by move_function_dbginfo.swift.
PublicCMOSymbols stores symbols which are made public by cross-module-optimizations.
Those symbols are primarily stored in SILModule and eventually used by TBD generation and validation.
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.
Leaks checking is not thread safe and e.g. lldb creates multiple SILModules in multiple threads, which would result in false alarms.
Ideally we would make it thread safe, e.g. by putting the instruction counters in the SILModule, but this would be a big effort and it's not worth doing it. Leaks checking in the frontend's and SILOpt's SILModule (not including SILModules created for module interface building) is a good enough test.
rdar://84688015
@objc actors implicitly inherit from the new, hidden
`SwiftNativeNSObject` class that inherits from `NSObject` yet provides
Swift-native reference counting, which is important for the actor
runtime's handling of zombies. However, `SwiftNativeNSObject` is only
available in the Swift runtime in newer OS versions (e.g., macOS
12.0/iOS 15.0), and is available in the back-deployed _Concurrency
library, but there is no stable place to link against for
back-deployed code. Tricky, tricky.
When back-deploying @objc actors, record `NSObject` as the superclass
in the metadata in the binary, because we cannot reference
`SwiftNativeNSObject`. Then, emit a static initializer to
dynamically look up `SwiftNativeNSObject` by name (which will find it
in either the back-deployment library, on older systems, or in the
runtime for newer systems), then swizzle that in as the superclass of
the @objc actor.
Fixes rdar://83919973.
A new LLVM IR affordance that allows expressing conditions under which globals
can be removed/dropped (even when marked with @llvm.used) is being discussed at:
- <https://reviews.llvm.org/D104496>
- <https://lists.llvm.org/pipermail/llvm-dev/2021-September/152656.html>
This is a preliminary implementation that marks runtime lookup records (namely
protocol records, type descriptors records and protocol conformance records)
with the !llvm.used.conditional descriptors. That allows link-time / LTO-time
removal of these records (by GlobalDCE) based on whether they're actually used
within the linkage unit. Effectively, this allows libraries that have a limited
and known set of clients, to be optimized against the client at LTO time, and
significantly reduce the code size of that library.
Parts of the implementation:
- New -conditional-runtime-records frontend flag to enable using !llvm.used.conditional
- IRGen code that emits these records can now emit these either as a single contiguous
array (asContiguousArray = true, the old way), which is used for JIT mode, or
as indivial globals (asContiguousArray = false), which is necessary for the
!llvm.used.conditional stripping to work.
- When records are emitted as individual globals, they have new names of
"\01l_protocol_" + mangled name of the protocol descriptor, and similarly for
other records.
- Fixed existing tests to account for individual records instead of a single array
- Added an IR level test, and an end-to-end execution test to demonstrate that
the !llvm.used.conditional-based stripping actually works.
- Witness method calls are done via @llvm.type.checked.load instrinsic call with a type identifier
- Type id of a witness method is the requirement's mangled name
- Witness tables get !type markers that list offsets and type ids of all methods in the wtable
- Added -enable-llvm-wme to enable Witness Method Elimination
- Added IR test and execution test
control swift extended frame information emission
On linux we default to disable the extended frame info (since the system
libraries don't support it).
On darwin the default is to automatically choose based on the deployment target.
The Concurrency library explicitly forces extended frame information and the
back deployment library explicitly disables it.
- Virtual calls are done via a @llvm.type.checked.load instrinsic call with a type identifier
- Type identifier of a vfunc is the base method's mangling
- Type descriptors and class metadata get !type markers that list offsets and type identifiers of all vfuncs
- The -enable-llvm-vfe frontend flag enables VFE
- Two added tests verify the behavior on IR and by executing a program
LLVM will eventually switch over to using global-isel on arm64 archs.
Setting this option (SWIFT_ENABLE_GLOBAL_ISEL_ARM64) can be used to experiment
with that in Swift before the switch happens.
LLVM commit 3adb89bb9f8e73c82787babb2f877fece7394770 updated the API of
this function to take a reference to a `SmallVectorImpl` instead of a
set to ensure that it behaves deterministically.
Same issue as with TBDGen. Clang doesn't hold onto the Datalayout object
anymore, but instead keeps the description string that is constructed on
the fly. This patch updates IRGen to behave the same way.
Previously, because partial apply forwarders for async functions were
not themselves fully-fledged async functions, they were not able to
handle dynamic functions. Specifically, the reason was that it was not
possible to produce an async function pointer for the partial apply
forwarder because the size to be used was not knowable.
Thanks to https://github.com/apple/swift/pull/36700, that cause has been
eliminated. With it, partial apply forwarders are fully-fledged async
functions and in particular have their own async function pointers.
Consequently, it is again possible for these partial apply forwarders to
handle non-constant function pointers.
Here, that behavior is restored, by way of reverting part of
ee63777332 while preserving the ABI it
introduced.
rdar://76122027
Previously, AsyncFunctionPointer constants were signed as code. That
was incorrect considering that these constants are in fact data. Here,
that is fixed.
rdar://76118522
* Adds support for generating code that uses swiftasync parameter lowering.
* Currently only arm64's llvm lowering supports the swift_async_context_addr intrinsic.
* Add arm64e pointer signing of updated swift_async_context_addr.
This commit needs the PR llvm-project#2291.
* [runtime] unittests should use just-built compiler if the runtime did
This will start to matter with the introduction of usage of swiftasync parameters which only very recent compilers support.
rdar://71499498
Previously Swift enabled the "UseOdrIndicator" ASan instrumentation mode
and gave no option to disable this. This probably wasn't intentional but
happened due to the fact the
`createModuleAddressSanitizerLegacyPassPass()` function has a default
value for the `UseOdrIndicator` parameter of `true` and in Swift we
never specified this parameter explicitly.
Clang disables the "UseOdrIndicator" mode by default but allows it to be
enabled using the `-fsanitize-address-use-odr-indicator` flag.
Having "UseOdrIndicator" off by default is probably the right
default choice because it bloats the binary. So this patch changes the
Swift compiler to match Clang's behavior.
This patch disables the "UseOdrIndicator" mode by default but adds a
hidden driver and frontend flag (`-sanitize-address-use-odr-indicator`)
to enable it. The flag is hidden so that we can remove it in the future
if needed.
A side effect of disabling "UseOdrIndicator" is that by we will no
longer use private aliases for poisoning globals. Private aliases were
introduced to avoid crashes
(https://github.com/google/sanitizers/issues/398) due to ODR violations
with non-instrumented binaries. On Apple platforms the use of two-level
namespaces probably means that using private aliases wasn't ever really
necessary to avoid crashes. On platforms with a flat linking namespace
(e.g. Linux) using private aliases might matter more but should users
actually run into problems they can either:
* Fix their environment to remove the ODR, thus avoiding the crash.
* Instrument the previously non-instrumented code to avoid the crash.
* Use the new `-sanitize-address-use-odr-indicator` flag
rdar://problem/69335186
Previously, the schema used a key intended for pointers to code. An
AsyncContextParent is actually a pointer to data, so that key was
incorrect. Here, that error is corrected and the schema now uses the
key for pointers to data.