From 09119a3db19b0d939e9bc02e3ddf3413d98fbd7a Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki Date: Sat, 13 May 2023 15:26:59 +0900 Subject: [PATCH] improve type inference of `Base.aligned_sizeof` This commit includes a bit of refactoring of `Base.aligned_sizeof` to make it more inference-friendly, especially in cases like `Base.aligned_sizeof(::Union{DataType,Union})`. In particular, it eliminates the chance of inference accounting for a method error of `datatype_alignment(::Union)` in the second branch. xref: --- base/reflection.jl | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/base/reflection.jl b/base/reflection.jl index 83f3967b98dbe..97f1ed14c6729 100644 --- a/base/reflection.jl +++ b/base/reflection.jl @@ -374,15 +374,18 @@ LLT_ALIGN(x, sz) = (x + sz - 1) & -sz # amount of total space taken by T when stored in a container function aligned_sizeof(@nospecialize T::Type) @_foldable_meta - if isbitsunion(T) - _, sz, al = uniontype_layout(T) - return LLT_ALIGN(sz, al) + if isa(T, Union) + if allocatedinline(T) + # NOTE this check is equivalent to `isbitsunion(T)`, we can improve type + # inference in the second branch with the outer `isa(T, Union)` check + _, sz, al = uniontype_layout(T) + return LLT_ALIGN(sz, al) + end elseif allocatedinline(T) al = datatype_alignment(T) return LLT_ALIGN(Core.sizeof(T), al) - else - return Core.sizeof(Ptr{Cvoid}) end + return Core.sizeof(Ptr{Cvoid}) end gc_alignment(sz::Integer) = Int(ccall(:jl_alignment, Cint, (Csize_t,), sz))