Skip to content

Commit

Permalink
tfunc: Constant fold isdefined for (dt::DataType).fields
Browse files Browse the repository at this point in the history
In PR #53750, we stopped constant folding `isdefined` for non-`const`
fields assuming that they may revert to `undef`. Unfortunately,
this broke `fieldcount` for `Tuple`s, causing significant inference
quality degradation. Adjust `fieldcount` to avoid this.
  • Loading branch information
Keno committed Apr 24, 2024
1 parent c38e7cd commit e32af99
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 3 deletions.
2 changes: 1 addition & 1 deletion base/boot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ macro _boundscheck() Expr(:boundscheck) end
TypeVar(@nospecialize(n)) = _typevar(n::Symbol, Union{}, Any)
TypeVar(@nospecialize(n), @nospecialize(ub)) = _typevar(n::Symbol, Union{}, ub)
TypeVar(@nospecialize(n), @nospecialize(lb), @nospecialize(ub)) = _typevar(n::Symbol, lb, ub)
UnionAll(@nospecialize(v), @nospecialize(t)) = ccall(:jl_type_unionall, Any, (Any, Any), v::TypeVar, t)
UnionAll(@nospecialize(v), @nospecialize(t)) = (@_foldable_meta; ccall(:jl_type_unionall, Any, (Any, Any), v::TypeVar, t))

const Memory{T} = GenericMemory{:not_atomic, T, CPU}
const MemoryRef{T} = GenericMemoryRef{:not_atomic, T, CPU}
Expand Down
7 changes: 5 additions & 2 deletions base/reflection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1003,12 +1003,15 @@ function datatype_fieldcount(t::DataType)
return fieldcount(types)
end
return nothing
elseif isabstracttype(t) || (t.name === Tuple.name && isvatuple(t))
elseif isabstracttype(t)
return nothing
end
if isdefined(t, :types)
if t.name === Tuple.name
isvatuple(t) && return nothing
return length(t.types)
end
# Equivalent to length(t.types), but `t.types` is lazy and we do not want
# to be forced to compute it.
return length(t.name.names)
end

Expand Down
3 changes: 3 additions & 0 deletions test/compiler/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5725,3 +5725,6 @@ let interp = CachedConditionalInterp();
result.linfo.def.name === :func_cached_conditional
end == 1
end

# fieldcount on `Tuple` should constant fold, even though `.fields` not const
@test fully_eliminated(Base.fieldcount, Tuple{Type{Tuple{Nothing, Int, Int}}})

0 comments on commit e32af99

Please sign in to comment.