Skip to content

Commit

Permalink
inference: remove special handlings of quasi-builtin functions (#48684)
Browse files Browse the repository at this point in the history
And fix their effect modeling.
  • Loading branch information
aviatesk authored Feb 16, 2023
1 parent a6e6fc9 commit fe6307d
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 46 deletions.
21 changes: 0 additions & 21 deletions base/compiler/abstractinterpretation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -813,9 +813,6 @@ is_method_pure(match::MethodMatch) = is_method_pure(match.method, match.spec_typ
function pure_eval_call(interp::AbstractInterpreter,
@nospecialize(f), applicable::Vector{Any}, arginfo::ArgInfo)
pure_eval_eligible(interp, f, applicable, arginfo) || return nothing
return _pure_eval_call(f, arginfo)
end
function _pure_eval_call(@nospecialize(f), arginfo::ArgInfo)
args = collect_const_args(arginfo, #=start=#2)
value = try
Core._apply_pure(f, args)
Expand Down Expand Up @@ -2041,26 +2038,8 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f),
end
argtypes = Any[typeof(<:), argtypes[3], argtypes[2]]
return abstract_call_known(interp, <:, ArgInfo(fargs, argtypes), si, sv, max_methods)
elseif la == 2 &&
(a2 = argtypes[2]; isa(a2, Const)) && (svecval = a2.val; isa(svecval, SimpleVector)) &&
istopfunction(f, :length)
# mark length(::SimpleVector) as @pure
return CallMeta(Const(length(svecval)), EFFECTS_TOTAL, MethodResultPure())
elseif la == 3 &&
(a2 = argtypes[2]; isa(a2, Const)) && (svecval = a2.val; isa(svecval, SimpleVector)) &&
(a3 = argtypes[3]; isa(a3, Const)) && (idx = a3.val; isa(idx, Int)) &&
istopfunction(f, :getindex)
# mark getindex(::SimpleVector, i::Int) as @pure
if 1 <= idx <= length(svecval) && isassigned(svecval, idx)
return CallMeta(Const(getindex(svecval, idx)), EFFECTS_TOTAL, MethodResultPure())
end
elseif la == 2 && istopfunction(f, :typename)
return CallMeta(typename_static(argtypes[2]), EFFECTS_TOTAL, MethodResultPure())
elseif la == 3 && istopfunction(f, :typejoin)
if is_all_const_arg(arginfo, #=start=#2)
val = _pure_eval_call(f, arginfo)
return CallMeta(val === nothing ? Type : val, EFFECTS_TOTAL, MethodResultPure())
end
elseif f === Core._hasmethod
return _hasmethod_tfunc(interp, argtypes, sv)
end
Expand Down
10 changes: 1 addition & 9 deletions base/compiler/ssair/inlining.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1693,14 +1693,6 @@ function linear_inline_eligible(ir::IRCode)
return true
end

# Check for a number of functions known to be pure
function ispuretopfunction(@nospecialize(f))
return istopfunction(f, :typejoin) ||
istopfunction(f, :isbits) ||
istopfunction(f, :isbitstype) ||
istopfunction(f, :promote_type)
end

function early_inline_special_case(
ir::IRCode, stmt::Expr, @nospecialize(type), sig::Signature,
state::InliningState)
Expand All @@ -1714,7 +1706,7 @@ function early_inline_special_case(
if is_pure_intrinsic_infer(f) && intrinsic_nothrow(f, argtypes[2:end])
return SomeCase(quoted(val))
end
elseif ispuretopfunction(f) || contains_is(_PURE_BUILTINS, f)
elseif contains_is(_PURE_BUILTINS, f)
return SomeCase(quoted(val))
elseif contains_is(_EFFECT_FREE_BUILTINS, f)
if _builtin_nothrow(optimizer_lattice(state.interp), f, argtypes[2:end], type)
Expand Down
16 changes: 15 additions & 1 deletion base/essentials.jl
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,19 @@ macro isdefined(s::Symbol)
return Expr(:escape, Expr(:isdefined, s))
end

"""
nameof(m::Module) -> Symbol
Get the name of a `Module` as a [`Symbol`](@ref).
# Examples
```jldoctest
julia> nameof(Base.Broadcast)
:Broadcast
```
"""
nameof(m::Module) = ccall(:jl_module_name, Ref{Symbol}, (Any,), m)

function _is_internal(__module__)
if ccall(:jl_base_relative_to, Any, (Any,), __module__)::Module === Core.Compiler ||
nameof(__module__) === :Base
Expand Down Expand Up @@ -696,8 +709,9 @@ end

# SimpleVector

@eval getindex(v::SimpleVector, i::Int) = Core._svec_ref($(Expr(:boundscheck)), v, i)
@eval getindex(v::SimpleVector, i::Int) = (@_foldable_meta; Core._svec_ref($(Expr(:boundscheck)), v, i))
function length(v::SimpleVector)
@_total_meta
t = @_gc_preserve_begin v
len = unsafe_load(Ptr{Int}(pointer_from_objref(v)))
@_gc_preserve_end t
Expand Down
4 changes: 2 additions & 2 deletions base/promotion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ Number
"""
typejoin() = Bottom
typejoin(@nospecialize(t)) = t
typejoin(@nospecialize(t), ts...) = (@_total_meta; typejoin(t, typejoin(ts...)))
typejoin(@nospecialize(t), ts...) = (@_foldable_meta; typejoin(t, typejoin(ts...)))
function typejoin(@nospecialize(a), @nospecialize(b))
@_total_meta
@_foldable_meta
if isa(a, TypeVar)
return typejoin(a.ub, b)
elseif isa(b, TypeVar)
Expand Down
13 changes: 0 additions & 13 deletions base/reflection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,6 @@

# name and module reflection

"""
nameof(m::Module) -> Symbol
Get the name of a `Module` as a [`Symbol`](@ref).
# Examples
```jldoctest
julia> nameof(Base.Broadcast)
:Broadcast
```
"""
nameof(m::Module) = ccall(:jl_module_name, Ref{Symbol}, (Any,), m)

"""
parentmodule(m::Module) -> Module
Expand Down
24 changes: 24 additions & 0 deletions test/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,30 @@ let mi = T26321{3,NTuple{3,Int}}((1,2,3)), mf = T26321{3,NTuple{3,Float64}}((1.0
@test a isa Vector{<:T26321{3}}
end

@test Base.return_types() do
typejoin(Int, UInt)
end |> only == Type{typejoin(Int, UInt)}
@test Base.return_types() do
typejoin(Int, UInt, Float64)
end |> only == Type{typejoin(Int, UInt, Float64)}

let res = @test_throws TypeError let
Base.Experimental.@force_compile
typejoin(1, 2)
nothing
end
err = res.value
@test err.func === :<:
end
let res = @test_throws TypeError let
Base.Experimental.@force_compile
typejoin(1, 2, 3)
nothing
end
err = res.value
@test err.func === :<:
end

# promote_typejoin returns a Union only with Nothing/Missing combined with concrete types
for T in (Nothing, Missing)
@test Base.promote_typejoin(Int, Float64) === Real
Expand Down

0 comments on commit fe6307d

Please sign in to comment.