Skip to content

Commit 3952c2c

Browse files
authored
Add @inline to Base.reinterpret (#57078)
Reinterpret contains quite a bit of code to handle padding, and so doesn't usually inline for structs. However, it frequently compiles down to a noop, making an inline unusually valuable.
1 parent dbcdf73 commit 3952c2c

File tree

2 files changed

+25
-15
lines changed

2 files changed

+25
-15
lines changed

base/essentials.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -726,6 +726,7 @@ julia> reinterpret(Tuple{UInt16, UInt8}, (0x01, 0x0203))
726726
727727
"""
728728
function reinterpret(::Type{Out}, x) where {Out}
729+
@inline
729730
if isprimitivetype(Out) && isprimitivetype(typeof(x))
730731
return bitcast(Out, x)
731732
end

base/reinterpretarray.jl

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -871,25 +871,34 @@ end
871871
return out[]
872872
else
873873
# mismatched padding
874-
GC.@preserve in out begin
875-
ptr_in = unsafe_convert(Ptr{In}, in)
876-
ptr_out = unsafe_convert(Ptr{Out}, out)
874+
return _reinterpret_padding(Out, x)
875+
end
876+
end
877877

878-
if fieldcount(In) > 0 && ispacked(Out)
879-
_copytopacked!(ptr_out, ptr_in)
880-
elseif fieldcount(Out) > 0 && ispacked(In)
881-
_copyfrompacked!(ptr_out, ptr_in)
882-
else
883-
packed = Ref{NTuple{inpackedsize, UInt8}}()
884-
GC.@preserve packed begin
885-
ptr_packed = unsafe_convert(Ptr{NTuple{inpackedsize, UInt8}}, packed)
886-
_copytopacked!(ptr_packed, ptr_in)
887-
_copyfrompacked!(ptr_out, ptr_packed)
888-
end
878+
# If the code reaches this part, it needs to handle padding and is unlikely
879+
# to compile to a noop. Therefore, we don't forcibly inline it.
880+
function _reinterpret_padding(::Type{Out}, x::In) where {Out, In}
881+
inpackedsize = packedsize(In)
882+
in = Ref{In}(x)
883+
out = Ref{Out}()
884+
GC.@preserve in out begin
885+
ptr_in = unsafe_convert(Ptr{In}, in)
886+
ptr_out = unsafe_convert(Ptr{Out}, out)
887+
888+
if fieldcount(In) > 0 && ispacked(Out)
889+
_copytopacked!(ptr_out, ptr_in)
890+
elseif fieldcount(Out) > 0 && ispacked(In)
891+
_copyfrompacked!(ptr_out, ptr_in)
892+
else
893+
packed = Ref{NTuple{inpackedsize, UInt8}}()
894+
GC.@preserve packed begin
895+
ptr_packed = unsafe_convert(Ptr{NTuple{inpackedsize, UInt8}}, packed)
896+
_copytopacked!(ptr_packed, ptr_in)
897+
_copyfrompacked!(ptr_out, ptr_packed)
889898
end
890899
end
891-
return out[]
892900
end
901+
return out[]
893902
end
894903

895904

0 commit comments

Comments
 (0)