Skip to content

Commit

Permalink
add fast-path to inference schanged computation
Browse files Browse the repository at this point in the history
when merging two frames (such as when handling exception frames),
most of the time new is old, but the computation here is
exponential in the number of variables so we want the inner computation
here to be ultra-fast in the common case

fix #15346
  • Loading branch information
vtjnash committed Nov 17, 2016
1 parent 5310bd6 commit 828cb10
Showing 1 changed file with 9 additions and 18 deletions.
27 changes: 9 additions & 18 deletions base/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1416,27 +1416,28 @@ function tmerge(typea::ANY, typeb::ANY)
end

function smerge(sa::Union{NotFound,VarState}, sb::Union{NotFound,VarState})
sa === sb && return sa
sa === NF && return sb
sb === NF && return sa
issubstate(sa,sb) && return sb
issubstate(sb,sa) && return sa
VarState(tmerge(sa.typ, sb.typ), sa.undef | sb.undef)
issubstate(sa, sb) && return sb
issubstate(sb, sa) && return sa
return VarState(tmerge(sa.typ, sb.typ), sa.undef | sb.undef)
end

tchanged(n::ANY, o::ANY) = o===NF || (n!==NF && !(n o))
schanged(n::ANY, o::ANY) = o===NF || (n!==NF && !issubstate(n, o))
@inline tchanged(n::ANY, o::ANY) = o === NF || (n !== NF && !(n o))
@inline schanged(n::ANY, o::ANY) = (n !== o) && (o === NF || (n !== NF && !issubstate(n, o)))

function stupdate!(state::Tuple{}, changes::StateUpdate)
newst = copy(changes.state)
if isa(changes.var, Slot)
newst[changes.var.id] = changes.vtype
end
newst
return newst
end

function stupdate!(state::VarTable, change::StateUpdate)
for i = 1:length(state)
if isa(change.var,Slot) && i == change.var.id
if isa(change.var, Slot) && i == (change.var::Slot).id
newtype = change.vtype
else
newtype = change.state[i]
Expand Down Expand Up @@ -1794,8 +1795,8 @@ function typeinf_frame(frame)
changes = abstract_interpret(stmt, s[pc]::Array{Any,1}, frame)
if changes === ()
# this line threw an error and there is no need to continue
#changes = s[pc]
break
changes = s[pc]
end
if frame.cur_hand !== ()
# propagate type info to exception handler
Expand Down Expand Up @@ -1872,16 +1873,6 @@ function typeinf_frame(frame)
push!(W, l)
s[l] = newstate
end
# if frame.handler_at[l] === 0
# frame.n_handlers += 1
# if frame.n_handlers > 25
# # too many exception handlers slows down inference a lot.
# # for an example see test/libgit2.jl on 0.5-pre master
# # around e.g. commit c072d1ce73345e153e4fddf656cda544013b1219
# inference_stack = (inference_stack::CallStack).prev
# return (ast0, Any, false)
# end
# end
frame.handler_at[l] = frame.cur_hand
elseif hd === :leave
for i = 1:((stmt.args[1])::Int)
Expand Down

0 comments on commit 828cb10

Please sign in to comment.