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

fix #29036, large slowdown in DelimitedFiles #29075

Merged
merged 2 commits into from
Sep 8, 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
27 changes: 19 additions & 8 deletions base/compiler/abstractinterpretation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,15 @@ function abstract_call_gf_by_type(@nospecialize(f), argtypes::Vector{Any}, @nosp
rettype = Bottom
edgecycle = false
edges = Any[]
nonbot = 0 # the index of the only non-Bottom inference result if > 0
seen = 0 # number of signatures actually inferred
for i in 1:napplicable
match = applicable[i]::SimpleVector
method = match[3]::Method
sig = match[1]
sigtuple = unwrap_unionall(sig)::DataType
splitunions = false
this_rt = Bottom
# TODO: splitunions = 1 < countunionsplit(sigtuple.parameters) * napplicable <= sv.params.MAX_UNION_SPLITTING
# currently this triggers a bug in inference recursion detection
if splitunions
Expand All @@ -71,24 +74,32 @@ function abstract_call_gf_by_type(@nospecialize(f), argtypes::Vector{Any}, @nosp
push!(edges, edge)
end
edgecycle |= edgecycle1::Bool
rettype = tmerge(rettype, rt)
rettype === Any && break
this_rt = tmerge(this_rt, rt)
this_rt === Any && break
end
rettype === Any && break
else
rt, edgecycle, edge = abstract_call_method(method, sig, match[2]::SimpleVector, sv)
this_rt, edgecycle, edge = abstract_call_method(method, sig, match[2]::SimpleVector, sv)
if edge !== nothing
push!(edges, edge)
end
rettype = tmerge(rettype, rt)
rettype === Any && break
end
if this_rt !== Bottom
if nonbot === 0
nonbot = i
else
nonbot = -1
end
end
seen += 1
rettype = tmerge(rettype, this_rt)
rettype === Any && break
end
if napplicable == 1 && !edgecycle && isa(rettype, Type) && sv.params.ipo_constant_propagation
# try constant propagation if only 1 method is inferred to non-Bottom
if nonbot > 0 && seen == napplicable && !edgecycle && isa(rettype, Type) && sv.params.ipo_constant_propagation
# 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[1]::SimpleVector, sv)
const_rettype = abstract_call_method_with_const_args(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
2 changes: 1 addition & 1 deletion base/tuple.jl
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ end

# this allows partial evaluation of bounded sequences of next() calls on tuples,
# while reducing to plain next() for arbitrary iterables.
indexed_iterate(t::Tuple, i::Int, state=1) = (@_inline_meta; (t[i], i+1))
indexed_iterate(t::Tuple, i::Int, state=1) = (@_inline_meta; (getfield(t, i), i+1))
indexed_iterate(a::Array, i::Int, state=1) = (@_inline_meta; (a[i], i+1))
function indexed_iterate(I, i)
x = iterate(I)
Expand Down
7 changes: 5 additions & 2 deletions src/julia-syntax.scm
Original file line number Diff line number Diff line change
Expand Up @@ -1916,16 +1916,19 @@
(ssavalue? x))
x (make-ssavalue)))
(ini (if (eq? x xx) '() `((= ,xx ,(expand-forms x)))))
(n (length lhss))
(st (gensy)))
`(block
,@ini
,.(map (lambda (i lhs)
(expand-forms
(lower-tuple-assignment
(list lhs st)
(if (= i (- n 1))
(list lhs)
(list lhs st))
`(call (top indexed_iterate)
,xx ,(+ i 1) ,.(if (eq? i 0) '() `(,st))))))
(iota (length lhss))
(iota n)
lhss)
(unnecessary ,xx))))))
((typed_hcat)
Expand Down
7 changes: 7 additions & 0 deletions test/compiler/compiler.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1990,3 +1990,10 @@ struct VoxelIndices{T <: Integer}
end
f28641(x::VoxelIndices, f) = getfield(x, f)
@test Base.return_types(f28641, (Any,Symbol)) == Any[Tuple]

# issue #29036
function f29036(s, i)
val, i = iterate(s, i)
val
end
@test Base.return_types(f29036, (String, Int)) == Any[Char]