Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

attempt to refine return type when it could be improved via PartialTuple #30385

Merged
merged 1 commit into from
Dec 18, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions base/compiler/abstractinterpretation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ function abstract_call_gf_by_type(@nospecialize(f), argtypes::Vector{Any}, @nosp
# if there's a possibility we could constant-propagate a better result
# (hopefully without doing too much work), try to do that now
# TODO: it feels like this could be better integrated into abstract_call_method / typeinf_edge
const_rettype = abstract_call_method_with_const_args(f, argtypes, applicable[nonbot]::SimpleVector, sv)
const_rettype = abstract_call_method_with_const_args(rettype, f, argtypes, applicable[nonbot]::SimpleVector, sv)
if const_rettype ⊑ rettype
# use the better result, if it's a refinement of rettype
rettype = const_rettype
Expand Down Expand Up @@ -142,7 +142,7 @@ function abstract_call_gf_by_type(@nospecialize(f), argtypes::Vector{Any}, @nosp
return rettype
end

function abstract_call_method_with_const_args(@nospecialize(f), argtypes::Vector{Any}, match::SimpleVector, sv::InferenceState)
function abstract_call_method_with_const_args(@nospecialize(rettype), @nospecialize(f), argtypes::Vector{Any}, match::SimpleVector, sv::InferenceState)
method = match[3]::Method
nargs::Int = method.nargs
method.isva && (nargs -= 1)
Expand All @@ -159,7 +159,7 @@ function abstract_call_method_with_const_args(@nospecialize(f), argtypes::Vector
end
end
end
haveconst || return Any
haveconst || improvable_via_constant_propagation(rettype) || return Any
sig = match[1]
sparams = match[2]::SimpleVector
code = code_for_method(method, sig, sparams, sv.params.world)
Expand Down Expand Up @@ -1060,7 +1060,7 @@ function typeinf_local(frame::InferenceState)
elseif hd === :return
pc´ = n + 1
rt = widenconditional(abstract_eval(stmt.args[1], s[pc], frame))
if !isa(rt, Const) && !isa(rt, Type) && (!isa(rt, PartialTuple) || frame.cached)
if !isa(rt, Const) && !isa(rt, Type) && !isa(rt, PartialTuple)
# only propagate information we know we can store
# and is valid inter-procedurally
rt = widenconst(rt)
Expand Down
6 changes: 3 additions & 3 deletions base/compiler/ssair/inlining.jl
Original file line number Diff line number Diff line change
Expand Up @@ -671,7 +671,7 @@ function analyze_method!(idx::Int, @nospecialize(f), @nospecialize(ft), @nospeci
return ConstantCase(quoted(linfo.inferred_const), method, Any[methsp...], metharg)
end

isconst, inferred = find_inferred(linfo, atypes, sv)
isconst, inferred = find_inferred(linfo, atypes, sv, stmttyp)
if isconst
return ConstantCase(inferred, method, Any[methsp...], metharg)
end
Expand Down Expand Up @@ -1152,7 +1152,7 @@ function ssa_substitute_op!(@nospecialize(val), arg_replacements::Vector{Any},
return urs[]
end

function find_inferred(linfo::MethodInstance, @nospecialize(atypes), sv::OptimizationState)
function find_inferred(linfo::MethodInstance, @nospecialize(atypes), sv::OptimizationState, @nospecialize(rettype))
# see if the method has a InferenceResult in the current cache
# or an existing inferred code info store in `.inferred`
haveconst = false
Expand All @@ -1163,7 +1163,7 @@ function find_inferred(linfo::MethodInstance, @nospecialize(atypes), sv::Optimiz
break
end
end
if haveconst
if haveconst || improvable_via_constant_propagation(rettype)
inf_result = cache_lookup(linfo, atypes, sv.params.cache) # Union{Nothing, InferenceResult}
else
inf_result = nothing
Expand Down
8 changes: 6 additions & 2 deletions base/compiler/typeinfer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -495,15 +495,19 @@ function typeinf_edge(method::Method, @nospecialize(atypes), sparams::SimpleVect
frame.parent = caller
end
typeinf(frame)
return frame.bestguess, frame.inferred ? frame.linfo : nothing
return widenconst_bestguess(frame.bestguess), frame.inferred ? frame.linfo : nothing
elseif frame === true
# unresolvable cycle
return Any, nothing
end
frame = frame::InferenceState
return frame.bestguess, nothing
return widenconst_bestguess(frame.bestguess), nothing
end

function widenconst_bestguess(bestguess)
!isa(bestguess, Const) && !isa(bestguess, Type) && return widenconst(bestguess)
return bestguess
end

#### entry points for inferring a MethodInstance given a type signature ####

Expand Down
9 changes: 9 additions & 0 deletions base/compiler/typeutils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -160,3 +160,12 @@ function unioncomplexity(t::DataType)
end
unioncomplexity(u::UnionAll) = max(unioncomplexity(u.body), unioncomplexity(u.var.ub))
unioncomplexity(@nospecialize(x)) = 0

function improvable_via_constant_propagation(@nospecialize(t))
if isconcretetype(t) && t <: Tuple
for p in t.parameters
p === DataType && return true
end
end
return false
end
12 changes: 12 additions & 0 deletions test/compiler/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2172,3 +2172,15 @@ f30394(foo::T1, ::Type{T2}) where {T2, T1 <: T2} = foo
f30394(foo, T2) = f30394(foo.foo_inner, T2)

@test Base.return_types(f30394, (Foo30394_2, Type{Base30394})) == Any[Base30394]

# PR #30385

g30385(args...) = h30385(args...)
h30385(f, args...) = f(args...)
f30385(T, y) = g30385(getfield, g30385(tuple, T, y), 1)
k30385(::Type{AbstractFloat}) = 1
k30385(x) = "dummy"
j30385(T, y) = k30385(f30385(T, y))

@test @inferred(j30385(AbstractFloat, 1)) == 1
@test @inferred(j30385(:dummy, 1)) == "dummy"