-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Optimize [U]Int.init(bitPattern:)
for optional pointer conversions
#81902
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
…n:)`. The branchy set `0` if `nil` approach doesn't translate well to machine code.
Can you expand on what the "idiomatic use in performance-sensitive code" for this operation is with some examples? What does that use case expect to happen when the optional pointer is nil? Why is hoisting the nil check and working with a non-optional pointer not the idiomatic solution? Separately, I'm slightly surprised that LLVM doesn't fuse these branches anyway, any ideas what information isn't getting passed forward from SIL, @meg-gupta? |
The short version of the story is that: I updated one of my text processing algorithms to accommodate |
I meant that Swift has two ways of solving my problem in an intentionally performant way: |
Imagine an |
I may note that you can apply this optimization to each of the following
I'll happily submit the corresponding changes, assuming bit-casting CC: @glessard |
The
[U]Int.init(bitPattern:)
initializers for optional pointer types currently result in suboptimal machine code. These conversions are semantically simple—reinterpreting the bit pattern of an optional pointer as an integer—but the current implementation introduces conditional branching, which penalizes idiomatic use in performance-sensitive code. Swift’s current runtime representation uses a zero bit pattern to representOptional<Unsafe*Pointer>.none
. If this representation is stable and guaranteed, we can useunsafeBitCast(_:to:)
to eliminate branching entirely.Benchmark: Compiler Explorer Outputs
This section shows some assembly for the current (foo) and the proposed (bar) approach:
aarch64 swiftc 6.1:
x86-64 swiftc 6.1:
Risk & Open Questions
The key question is whether the zero bit pattern representation of
Optional<Unsafe*Pointer>.none
is a formal guarantee of the Swift ABI or an implementation detail subject to change. If this layout is not formally guaranteed by the Swift ABI, then this optimization might introduce undefined behavior in future Swift versions.