Skip to content

Commit

Permalink
Merge pull request #15575 from JuliaLang/jn/typeinf_opt
Browse files Browse the repository at this point in the history
type inference improvements
  • Loading branch information
vtjnash committed Apr 6, 2016
2 parents 95607ed + cb5e2fa commit 61f2d2b
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 34 deletions.
5 changes: 4 additions & 1 deletion base/coreimg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@ include("operators.jl")
include("pointer.jl")
const checked_add = +
const checked_sub = -
(::Type{T}){T}(arg) = convert(T, arg)::T
if !isdefined(Main, :Base)
# conditional to allow redefining Core.Inference after base exists
(::Type{T}){T}(arg) = convert(T, arg)::T
end

# core array operations
include("abstractarray.jl")
Expand Down
54 changes: 24 additions & 30 deletions base/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ type InferenceState

# exception handlers
cur_hand = ()
handler_at = Any[ 0 for i=1:n ]
handler_at = Any[ () for i=1:n ]
n_handlers = 0

W = IntSet()
Expand Down Expand Up @@ -1401,31 +1401,24 @@ function stupdate!(state::VarTable, change::StateUpdate)
return state
end

stupdate!(state::Tuple{}, changes::VarTable) = copy(changes)

function stupdate!(state::VarTable, changes::VarTable)
newstate = false
for i = 1:length(state)
newtype = changes[i]
oldtype = state[i]
if schanged(newtype, oldtype)
newstate = state
state[i] = smerge(oldtype, newtype)
end
end
return state
return newstate
end

stchanged(new::Tuple{}, old::Tuple{}) = false
stchanged(new, old::Tuple{}) = true
stupdate!(state::Tuple{}, changes::VarTable) = copy(changes)

function stchanged(new::VarTable, old::VarTable)
is(old,()) && return true
for i = 1:length(new)
newtype = new[i]
oldtype = old[i]
schanged(newtype, oldtype) && return true
end
return false
end
stupdate!(state::Tuple{}, changes::Tuple{}) = false

#### helper functions for typeinf initialization and looping ####

function stchanged(new::StateUpdate, old::VarTable)
is(old,()) && return true
Expand Down Expand Up @@ -1744,11 +1737,7 @@ function typeinf_frame(frame)
delete!(W, pc)
frame.currpc = pc
frame.static_typeof = false
if frame.handler_at[pc] === 0
frame.handler_at[pc] = frame.cur_hand
else
frame.cur_hand = frame.handler_at[pc]
end
frame.cur_hand = frame.handler_at[pc]
stmt = frame.linfo.code[pc]
changes = abstract_interpret(stmt, s[pc]::Array{Any,1}, frame)
if changes === ()
Expand All @@ -1761,9 +1750,10 @@ function typeinf_frame(frame)
if frame.cur_hand !== ()
# propagate type info to exception handler
l = frame.cur_hand[1]
if stchanged(changes, s[l])
newstate = stupdate!(s[l], changes)
if newstate !== false
push!(W, l)
s[l] = stupdate!(s[l], changes)
s[l] = newstate
end
end
pc´ = pc+1
Expand Down Expand Up @@ -1796,10 +1786,11 @@ function typeinf_frame(frame)
else
# general case
frame.handler_at[l] = frame.cur_hand
if stchanged(changes, s[l])
newstate = stupdate!(s[l], changes)
if newstate !== false
# add else branch to active IP list
push!(W, l)
s[l] = stupdate!(s[l], changes)
s[l] = newstate
end
end
elseif is(hd, :type_goto)
Expand Down Expand Up @@ -1845,9 +1836,10 @@ function typeinf_frame(frame)
l = frame.cur_hand[1]
old = s[l]
new = s[pc]::Array{Any,1}
if old === () || stchanged(new, old::Array{Any,1})
newstate = stupdate!(old, new)
if newstate !== false
push!(W, l)
s[l] = stupdate!(old, new)
s[l] = newstate
end
# if frame.handler_at[l] === 0
# frame.n_handlers += 1
Expand All @@ -1866,9 +1858,11 @@ function typeinf_frame(frame)
end
end
end
if pc´<=n && (frame.handler_at[pc´] = frame.cur_hand; true) &&
stchanged(changes, s[pc´])
s[pc´] = stupdate!(s[pc´], changes)
pc´ > n && break # can't proceed with the fast-path fall-through
frame.handler_at[pc´] = frame.cur_hand
newstate = stupdate!(s[pc´], changes)
if newstate !== false
s[pc´] = newstate
pc = pc´
elseif pc´ in W
pc = pc´
Expand Down Expand Up @@ -2361,7 +2355,7 @@ function inlineable(f::ANY, ft::ANY, e::Expr, atypes::Vector{Any}, sv::Inference
if linfo === NF
return NF
end
if linfo.pure && isconstantargs(argexprs, atypes, sv)
if isa(f, ft) && linfo.pure && isconstantargs(argexprs, atypes, sv)
# check if any arguments aren't effect_free and need to be kept around
stmts = Any[]
for i = 1:length(argexprs)
Expand Down
10 changes: 8 additions & 2 deletions base/operators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,14 @@ isless(x::AbstractFloat, y::AbstractFloat) = (!isnan(x) & isnan(y)) | (signbit(x
isless(x::Real, y::AbstractFloat) = (!isnan(x) & isnan(y)) | (signbit(x) & !signbit(y)) | (x < y)
isless(x::AbstractFloat, y::Real ) = (!isnan(x) & isnan(y)) | (signbit(x) & !signbit(y)) | (x < y)

=={T}(::Type{T}, ::Type{T}) = true # encourage more specialization on types (see #11425)
==(T::Type, S::Type) = typeseq(T, S)
function ==(T::Type, S::Type)
@_pure_meta
typeseq(T, S)
end
function !=(T::Type, S::Type)
@_pure_meta
!(T == S)
end

## comparison fallbacks ##

Expand Down
2 changes: 1 addition & 1 deletion base/test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ macro test(ex)
if isa(ex, Expr) && ex.head == :comparison
# Generate a temporary for every term in the expression
n = length(ex.args)
terms = [gensym() for i in 1:n]
terms = [GenSym(i) for i in 1:n]
# Create a new block that evaluates each term in the
# comparison indivudally
comp_block = Expr(:block)
Expand Down

0 comments on commit 61f2d2b

Please sign in to comment.