Skip to content

Commit

Permalink
compiler: more accurate isdefined_tfunc for NamedTuple arg: (#37830)
Browse files Browse the repository at this point in the history
e.g. this will exclude unnecessary runtime calls of `haskey` when a keyword 
argument is inferred as non-concrete type
```julia
f(a; b = nothing, c = nothing) = return
let
    b = rand((nothing,1,1.))
    f(0; b)
end
```
  • Loading branch information
aviatesk authored Oct 8, 2020
1 parent 5208a50 commit 025d106
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 0 deletions.
5 changes: 5 additions & 0 deletions base/compiler/tfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,11 @@ function isdefined_tfunc(@nospecialize(arg1), @nospecialize(sym))
elseif a1.name === _NAMEDTUPLE_NAME
if isconcretetype(a1)
return Const(false)
else
ns = a1.parameters[1]
if isa(ns, Tuple)
return Const(1 <= idx <= length(ns))
end
end
elseif idx <= 0 || (!isvatuple(a1) && idx > fieldcount(a1))
return Const(false)
Expand Down
10 changes: 10 additions & 0 deletions test/compiler/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1072,6 +1072,16 @@ end
@test isdefined_tfunc(Tuple{Any,Vararg{Any}}, Const(1)) === Const(true)
@test isdefined_tfunc(Tuple{Any,Vararg{Any}}, Const(2)) === Bool
@test isdefined_tfunc(Tuple{Any,Vararg{Any}}, Const(3)) === Bool
@testset "isdefined check for `NamedTuple`s" begin
# concrete `NamedTuple`s
@test isdefined_tfunc(NamedTuple{(:x,:y),Tuple{Int,Int}}, Const(:x)) === Const(true)
@test isdefined_tfunc(NamedTuple{(:x,:y),Tuple{Int,Int}}, Const(:y)) === Const(true)
@test isdefined_tfunc(NamedTuple{(:x,:y),Tuple{Int,Int}}, Const(:z)) === Const(false)
# non-concrete `NamedTuple`s
@test isdefined_tfunc(NamedTuple{(:x,:y),<:Tuple{Int,Any}}, Const(:x)) === Const(true)
@test isdefined_tfunc(NamedTuple{(:x,:y),<:Tuple{Int,Any}}, Const(:y)) === Const(true)
@test isdefined_tfunc(NamedTuple{(:x,:y),<:Tuple{Int,Any}}, Const(:z)) === Const(false)
end

@noinline map3_22347(f, t::Tuple{}) = ()
@noinline map3_22347(f, t::Tuple) = (f(t[1]), map3_22347(f, Base.tail(t))...)
Expand Down

0 comments on commit 025d106

Please sign in to comment.