Call through to _swift_modifyAtReferenceWritableKeyPath_impl in that case. This fixes an assertion failure (or worse) when upcasting a ReferenceWritableKeyPath and then using subscript(keyPath:) to modify a value with it.
rdar://74191390
Apparently, even with Dispatch running on Linux, these tests are
unsupported on those platforms. These also fail on OpenBSD, so
presumably these should be marked unsupported on this platform too.
* SwiftDtoa v2: Better, Smaller, Faster floating-point formatting
SwiftDtoa is the C/C++ code used in the Swift runtime to produce the textual representations used by the `description` and `debugDescription` properties of the standard Swift floating-point types.
This update includes a number of algorithmic improvements to SwiftDtoa to improve portability, reduce code size, and improve performance but does not change the actual output.
About SwiftDtoa
===============
In early versions of Swift, the `description` properties used the C library `sprintf` functionality with a fixed number of digits.
In 2018, that logic was replaced with the first version of SwiftDtoa which used used a fast, adaptive algorithm to automatically choose the correct number of digits for a particular value.
The resulting decimal output is always:
* Accurate. Parsing the decimal form will yield exactly the same binary floating-point value again. This guarantee holds for any parser that accurately implements IEEE 754. In particular, the Swift standard library can guarantee that for any Double `d` that is not a NaN, `Double(d.description) == d`.
* Short. Among all accurate forms, this form has the fewest significant digits. (Caution: Surprisingly, this is not the same as minimizing the number of characters. In some cases, minimizing the number of characters requires producing additional significant digits.)
* Close. If there are multiple accurate, short forms, this code chooses the decimal form that is closest to the exact binary value. If there are two exactly the same distance, the one with an even final digit will be used.
Algorithms that can produce this "optimal" output have been known since at least 1990, when Steele and White published their Dragon4 algorithm.
However, Dragon4 and other algorithms from that period relied on high-precision integer arithmetic, which made them slow.
More recently, a surge of interest in this problem has produced dramatically better algorithms that can produce the same results using only fast fixed-precision arithmetic.
This format is ideal for JSON and other textual interchange: accuracy ensures that the value will be correctly decoded, shortness minimizes network traffic, and the existence of high-performance algorithms allows this form to be generated more quickly than many `printf`-based implementations.
This format is also ideal for logging, debugging, and other general display. In particular, the shortness guarantee avoids the confusion of unnecessary additional digits, so that the result of `1.0 / 10.0` consistently displays as `0.1` instead of `0.100000000000000000001`.
About SwiftDtoa v2
==================
Compared to the original SwiftDtoa code, this update is:
**Better**:
The core logic is implemented using only C99 features with 64-bit and smaller integer arithmetic.
If available, 128-bit integers are used for better performance.
The core routines do not require any floating-point support from the C/C++ standard library and with only minor modifications should be usable on systems with no hardware or software floating-point support at all.
This version also has experimental support for IEEE 754 binary128 format, though this support is obviously not included when compiling for the Swift standard library.
**Smaller**:
Code size reduction compared to the earlier versions was a primary goal for this effort.
In particular, the new binary128 support shares essentially all of its code with the float80 implementation.
**Faster**:
Even with the code size reductions, all formats are noticeably faster.
The primary performance gains come from three major changes:
Text digits are now emitted directly in the core routines in a form that requires only minimal adjustment to produce the final text.
Digit generation produces 2, 4, or even 8 digits at a time, depending on the format.
The double logic optimistically produces 7 digits in the initial scaling with a Ryu-inspired backtracking when fewer digits suffice.
SwiftDtoa's algorithms
======================
SwiftDtoa started out as a variation of Florian Loitsch' Grisu2 that addressed the shortness failures of that algorithm.
Subsequent work has incorporated ideas from Errol3, Ryu, and other sources to yield a production-quality implementation that is performance- and size-competitive with current research code.
Those who wish to understand the details can read the extensive comments included in the code.
Note that float16 actually uses a different algorithm than the other formats, as the extremely limited range can be handled with much simpler techniques.
The float80/binary128 logic sacrifices some performance optimizations in order to minimize the code size for these less-used formats; the goal for SwiftDtoa v2 has been to match the float80 performance of earlier implementations while reducing code size and widening the arithmetic routines sufficiently to support binary128.
SwiftDtoa Testing
=================
A newly-developed test harness generates several large files of test data that include known-correct results computed with high-precision arithmetic routines.
The test files include:
* Critical values generated by the algorithm presented in the Errol paper (about 48 million cases for binary128)
* Values for which the optimal decimal form is exactly midway between two binary floating-point values.
* All exact powers of two representable in this format.
* Floating-point values that are close to exact powers of ten.
In addition, several billion random values for each format were compared to the results from other implementations.
For binary16 and binary32 this provided exhaustive validation of every possible input value.
Code Size and Performance
=========================
The tables below summarize the code size and performance for the SwiftDtoa C library module by itself on several different processor architectures.
When used from Swift, the `.description` and `.debugDescription` implementations incur additional overhead for creating and returning Swift strings that are not captured here.
The code size tables show the total size in bytes of the compiled `.o` object files for a particular version of that code.
The headings indicate the floating-point formats supported by that particular build (e.g., "16,32" for a version that supports binary16 and binary32 but no other formats).
The performance numbers below were obtained from a custom test harness that generates random bit patterns, interprets them as the corresponding floating-point value, and averages the overall time.
For float80, the random bit patterns were generated in a way that avoids generating invalid values.
All code was compiled with the system C/C++ compiler using `-O2` optimization.
A few notes about particular implementations:
* **SwiftDtoa v1** is the original SwiftDtoa implementation as committed to the Swift runtime in April 2018.
* **SwiftDtoa v1a** is the same as SwiftDtoa v1 with added binary16 support.
* **SwiftDtoa v2** can be configured with preprocessor macros to support any subset of the supported formats. I've provided sizes here for several different build configurations.
* **Ryu** (Ulf Anders) implements binary32 and binary64 as completely independent source files. The size here is the total size of the two .o object files.
* **Ryu(size)** is Ryu compiled with the `RYU_OPTIMIZE_SIZE` option.
* **Dragonbox** (Junekey Jeon). The size here is the compiled size of a simple `.cpp` file that instantiates the template for the specified formats, plus the size of the associated text output logic.
* **Dragonbox(size)** is Dragonbox compiled to minimize size by using a compressed power-of-10 table.
* **gdtoa** has a very large feature set. For this reason, I excluded it from the code size comparison since I didn't consider the numbers to be comparable to the others.
x86_64
----------------
These were built using Apple clang 12.0.5 on a 2019 16" MacBook Pro (2.4GHz 8-core Intel Core i9) running macOS 11.1.
**Code Size**
Bold numbers here indicate the configurations that have shipped as part of the Swift runtime.
| | 16,32,64,80 | 32,64,80 | 32,64 |
|---------------|------------:|------------:|------------:|
|SwiftDtoa v1 | | **15128** | |
|SwiftDtoa v1a | **16888** | | |
|SwiftDtoa v2 | **20220** | 18628 | 8248 |
|Ryu | | | 40408 |
|Ryu(size) | | | 23836 |
|Dragonbox | | | 23176 |
|Dragonbox(size)| | | 15132 |
**Performance**
| | binary16 | binary32 | binary64 | float80 | binary128 |
|--------------|---------:|---------:|---------:|--------:|----------:|
|SwiftDtoa v1 | | 25ns | 46ns | 82ns | |
|SwiftDtoa v1a | 37ns | 26ns | 47ns | 83ns | |
|SwiftDtoa v2 | 22ns | 19ns | 31ns | 72ns | 90ns |
|Ryu | | 19ns | 26ns | | |
|Ryu(size) | | 17ns | 24ns | | |
|Dragonbox | | 19ns | 24ns | | |
|Dragonbox(size) | | 19ns | 29ns | | |
|gdtoa | 220ns | 381ns | 1184ns | 16044ns | 22800ns |
ARM64
----------------
These were built using Apple clang 12.0.0 on a 2020 M1 Mac Mini running macOS 11.1.
**Code Size**
| | 16,32,64 | 32,64 |
|---------------|---------:|------:|
|SwiftDtoa v1 | | 7436 |
|SwiftDtoa v1a | 9124 | |
|SwiftDtoa v2 | 9964 | 8228 |
|Ryu | | 35764 |
|Ryu(size) | | 16708 |
|Dragonbox | | 27108 |
|Dragonbox(size)| | 19172 |
**Performance**
| | binary16 | binary32 | binary64 | float80 | binary128 |
|--------------|---------:|---------:|---------:|--------:|----------:|
|SwiftDtoa v1 | | 21ns | 39ns | | |
|SwiftDtoa v1a | 17ns | 21ns | 39ns | | |
|SwiftDtoa v2 | 15ns | 17ns | 29ns | 54ns | 71ns |
|Ryu | | 15ns | 19ns | | |
|Ryu(size) | | 29ns | 24ns | | |
|Dragonbox | | 16ns | 24ns | | |
|Dragonbox(size) | | 15ns | 34ns | | |
|gdtoa | 143ns | 242ns | 858ns | 25129ns | 36195ns |
ARM32
----------------
These were built using clang 8.0.1 on a BeagleBone Black (500MHz ARMv7) running FreeBSD 12.1-RELEASE.
**Code Size**
| | 16,32,64 | 32,64 |
|---------------|---------:|------:|
|SwiftDtoa v1 | | 8668 |
|SwiftDtoa v1a | 10356 | |
|SwiftDtoa v2 | 9796 | 8340 |
|Ryu | | 32292 |
|Ryu(size) | | 14592 |
|Dragonbox | | 29000 |
|Dragonbox(size)| | 21980 |
**Performance**
| | binary16 | binary32 | binary64 | float80 | binary128 |
|--------------|---------:|---------:|---------:|--------:|----------:|
|SwiftDtoa v1 | | 459ns | 1152ns | | |
|SwiftDtoa v1a | 383ns | 451ns | 1148ns | | |
|SwiftDtoa v2 | 202ns | 357ns | 715ns | 2720ns | 3379ns |
|Ryu | | 345ns | 5450ns | | |
|Ryu(size) | | 786ns | 5577ns | | |
|Dragonbox | | 300ns | 904ns | | |
|Dragonbox(size) | | 294ns | 1021ns | | |
|gdtoa | 2180ns | 4749ns | 18742ns |293000ns | 440000ns |
* This is fast enough now even for non-optimized test runs
* Fix float80 Nan/Inf parsing, comment more thoroughly
A follow-on to b436825948 where
-m${platform}-version-min was traded for -target. The lit substitution
for %target-clang was relying on -arch and -version-min to specify the
intended platform version to the linker. With the removal of
version-min, only arch was given, so a fallback platform was selected.
For the iPhone simulator, for example, this is iOS 10.99 despite there
being no such simulator for that deployment version. Provide the variant
triple everywhere instead. This has the added benefit of unifying the
special paths catalyst takes.
Fixes rdar://73174820
Otherwise, this uniqueness check will unexpectedly succeed when tests
run in optimize mode and 'c' is destroyed early:
let c = C()
var b = B(native: c, isFlagged: flag)
//...
expectFalse(b.isUniquelyReferencedUnflaggedNative())
// Keep 'c' alive for the isUniquelyReferenced check above.
_fixLifetime(c)
Fixes rdar://72957398 ([CanonicalOSSA] Add a _fixLifetime to
stdlib/BridgeStorage.swift test.)
On Linux with -O:
Could not cast value of type 'Swift.Optional<Swift.AnyObject>'
(0x7fa5f4285b60) to 'weaktest.NativeSwiftClass' (0x563acd3f30d8).
weak var verifier: AnyObject?
do {
let parent = NativeSwiftClassHasWeak(x: 1010)
let child = NativeSwiftClass(x: 2020)
verifier = child
parent.weakProperty = child
let mirror = Mirror(reflecting: parent)
let children = Array(mirror.children)
let extractedChild = children[0].1 as! NativeSwiftClass
expectNotNil(extractedChild)
expectNotNil(verifier)
}
expectNil(verifier)
Here the expression children[-1].1 is a weak reference refering back
to 'child'. There's nothing keeping that 'child' object alive. On
Linux, the optimizer is able to destroy child before the dynamic type
cast. The cast attempts to cast a nil weak reference and fails.
Fixes rdar://72933297 ([CanonicalOSSA] Fix WeakMirror.swift test that
assumes object lifetime)
Unchecked APIs must still perform checks in debug builds to ensure that invariants aren’t violated.
(I.e., these aren’t a license to perform invalid operations — they just let us get rid of the checks when we know for sure they are unnecessary.)
While the existing _forEachField in ReflectionMirror.swift
already gives the offsets and types for each field, this isn't
enough information to construct a keypath for that field in
order to modify it.
For reference, this should be sufficent to implement the features
described here: (https://forums.swift.org/t/storedpropertyiterable/19218/62)
purely at runtime without any derived conformances for many types.
Note: Since there isn't enough reflection information for
`.mutatingGetSet` fields, this means that we're not able to support
reflecting certain types of fields (functions, nonfinal class fields,
etc). Whether this is an error or not is controlled by the `.ignoreUnknown`
option.
Due to an unstable (and undesirable) calling convention in the LLVM layer for x86, I had previously marked Float16 unconditionally unavailable on macOS. My hope was that Intel would stabilize the calling convention and we could make it available on both macOS platforms at the same time. Unfortunately, that hasn't happened, and we want to make the type available for macOS/arm users.
So, I am making the availability mirror Float80--the type will be unavailable for macOS on x86_64, and available on all other platforms (the other x86 platforms don't have a binary-stability guarantee to worry about). This isn't ideal. In particular, if/when the calling conventions for Float16 stabilize in LLVM, we would want to make the type available, but it would then have _different_ availability for different architectures of macOS, which the current availability system is not well-equipped to handle (it's possible, but not very ergonomic). Nonetheless, this seems like the best option.
The good news is that because the full API is already built in Swift (and simply marked unavailable), we can simply add macOS 11.0 availability for these API and it will work.
Call through to swift_setAtReferenceWritableKeyPath in that case. This fixes an assertion failure (or worse) when upcasting a ReferenceWritableKeyPath and then using subscript(keyPath:) to write a value with it.
rdar://problem/70609888
In debug configurations, fatal error messages include file & line number information. This update presents this information in a format matching the diagnostic conventions used by the compiler, which can be a slight productivity boost.
Code compiled with optimizations enabled (which is most production code) does not output this information, so it isn’t affected by this change.
Original format:
Fatal error: A suffusion of yellow: file calc.swift, line 5
New format:
calc.swift:5: Fatal error: A suffusion of yellow
Resolves rdar://68484891
Let's consider conditional requirement failure to mean that parent
conformance requirement wasn't satisfied and nothing more, that helps
to disambiguate certain situations and avoid filtering out conditional
failures.
Resolves: rdar://problem/64844584
Compute a slice of ambiguous overload choices related to an aggregated fix
and if such a slice points to a single overload diagnose it as non-ambiguous.
Previously, overflow and underflow both caused this to return `nil`, which causes several problems:
* It does not distinguish between a large but valid input and a malformed input. `Float("3.402824e+38")` is perfectly well-formed but returns nil
* It differs from how the compiler handles literals. As a result, `Float(3.402824e+38)` is very different from `Float("3.402824e+38")`
* It's inconsistent with Foundation Scanner()
* It's inconsistent with other programming languages
This is exactly the same as #25313
Fixes rdar://problem/36990878
This replaces swiftMSVCRT with swiftCRT. The big difference here is
that the `visualc` module is no longer imported nor exported. The
`visualc` module remains in use for a singular test wrt availability,
but this should effectively remove the need for the `visualc` module.
The difference between the MSVCRT and ucrt module was not well
understood by most. MSVCRT provided ucrt AND visualc, combining pieces
of the old MSVCRT and the newer ucrt. The ucrt module is what you
really wanted most of the time, however, would need to use MSVCRT for
the convenience aliases for type-generic math and the deprecated math
constants.
Unfortunately, we cannot shadow the `ucrt` module and create a Swift SDK
overlay for ucrt as that seems to result in circular dependencies when
processing the `_Concurrency` module.
Although this makes using the C library easier for most people, it has a
more important subtle change: it cleaves the dependency on visualc.
This means that this enables use of Swift without Visual Studio for the
singular purpose of providing 3 header files. Additionally, it removes
the need for the installation of 2 of the 4 support files. This greatly
simplifies the deployment process on Windows.