> On Oct 19, 2016, at 8:42 PM, Joe Groff via swift-dev <swift-dev@swift.org> > wrote: > I had a discussion with Steve this morning about the potential for enum > layout optimization with floating-point payloads. One great thing about > floating-point is that it has NaNs, and lots of them. For the most part, the > only significant semantic difference among these NaNs is whether they're > signaling or not, so it's tempting to reclaim some of these representations > for other purposes. Javascript engines are of course famous for > "NaN-encoding" values, representing JS numbers as native Doubles and packing > pointers to non-number object instances into the same representation by using > NaN bit patterns. In Swift, we could do similar things for enums with > floating-point payloads, making 'Float?' and 'Double?' take the same amount > of space as non-optionals, and automatically applying Javascript-style layout > optimizations when defining enums with mixed float and object payloads. IEEE > 754 is ambivalent about the role of NaN payloads, and there are libraries > that use payloads for interesting diagnostic purposes, but the standard > declares up front that it "does not interpret the sign of a NaN" (section > 6.3). Reserving "negative" NaNs with the sign bit set as extra inhabitants > could let us do enum layout optimization without interfering with the ability > for libraries to freely use NaN payloads. > > However, the way we usually handle enum optimization with extra inhabitants > is problematic for floats. We normally say that it is undefined behavior for > a value to have an extra inhabitant representation—a class reference cannot > be null, a Bool can only be 0 or 1, and so on. With floats, we need to > interoperate with numerics code not written in Swift, and we want to be able > to read floating-point data out of memory that may use arbitrary bit > patterns. We don't want every double-returning C function or load from memory > to require a check for reserved values afterward. Making it undefined > behavior for floats to have "extra inhabitant" representations is thus > probably not practical. > > Instead of saying that extra inhabitants are undefined behavior, we could > instead continue to allow Floats and Doubles to have arbitrary bit patterns, > and only check for reserved values at the point we construct an enum that > wants to use reserved values for layout. If we reserve negative NaNs, then > for example, constructing a Float? or Double? from a nonoptional value would > check whether the payload value is NaN and if so, clear the sign bit at that > point. That way, we don't have any ABI problems with Floats and Doubles from > foreign sources, but still get the benefits of layout optimization for Swift > types. On the other hand, this would mean that supposedly-idempotent > operations like '.some(x)!' lose the sign information for NaNs. Since we > wouldn't want to prevent the optimizer from folding those kinds of operations > away, we could define Swift's semantics to say that querying the sign of a > NaN value produces an unspecified value. This matches the intent of IEEE 754, > and shouldn't impact most numerics code in practice. If we were interested in > pursuing enum layout optimization with float payloads, I think this would be > the best approach.
As an implementation matter, is this going to significantly complicate the "make a T? from an unknown T" path? Currently, I think that logic just asks whether a type has extra inhabitants; it doesn't have any notion of having to rewrite actual values to avoid colliding with the "extra" inhabitants. John. _______________________________________________ swift-dev mailing list swift-dev@swift.org https://lists.swift.org/mailman/listinfo/swift-dev