From 97235f223ad03b53bbe3e1a0f752283a9806177e Mon Sep 17 00:00:00 2001 From: "McCoy R. Becker" Date: Fri, 21 Aug 2020 09:16:13 -0400 Subject: [PATCH 1/4] Infinite type inference test. --- test/trace.jl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/trace.jl b/test/trace.jl index ed5c8d1..b67af07 100644 --- a/test/trace.jl +++ b/test/trace.jl @@ -145,6 +145,15 @@ tr = @trace pow(2, 3) tr = @trace pow(Int, Int) @test returntype(tr) == Int +function pow(x, n) + n == one(n) && return x + n <= zero(n) && return zero(x) + return x*pow(x, n-1) +end + +tr = @trace pow(Float64, Int) +@test returntype(tr) == Float64 + function sumabs2(xs) s = zero(eltype(xs)) for i = 1:length(xs) From ad46e7cc08286153ee4b099a076ac492dd1eb45b Mon Sep 17 00:00:00 2001 From: femtomc Date: Wed, 7 Oct 2020 21:16:27 -0400 Subject: [PATCH 2/4] Fixed QuoteNode fallthrough. --- .gitignore | 1 + src/infer.jl | 103 ++++++++++++++++++++++++------------------------ src/lib/base.jl | 3 +- 3 files changed, 54 insertions(+), 53 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d287cd3 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +debug diff --git a/src/infer.jl b/src/infer.jl index 9edc3ba..37a6b7d 100644 --- a/src/infer.jl +++ b/src/infer.jl @@ -182,70 +182,71 @@ function openbranches(bl) end function step!(inf::Inference) - frame, b, f, ip = pop!(inf.queue) - block, stmts = getblock(frame, b, f) - uninline!(frame, b, f) - if ip <= length(stmts) - var = stmts[ip] - st = block[var] - if isexpr(st.expr, :call) - T = infercall!(inf, (frame, b, f, ip), block, st.expr) - if T != Union{} - block.ir[var] = stmt(block[var], type = _union(st.type, T)) - push!(inf.queue, (frame, b, f, ip+1)) - end - elseif isexpr(st.expr, :inbounds) - push!(inf.queue, (frame, b, f, ip+1)) + frame, b, f, ip = pop!(inf.queue) + block, stmts = getblock(frame, b, f) + uninline!(frame, b, f) + if ip <= length(stmts) + var = stmts[ip] + st = block[var] + if isexpr(st.expr, :call) + T = infercall!(inf, (frame, b, f, ip), block, st.expr) + if T != Union{} + block.ir[var] = stmt(block[var], type = _union(st.type, T)) + push!(inf.queue, (frame, b, f, ip+1)) + end + elseif isexpr(st.expr, :inbounds) + push!(inf.queue, (frame, b, f, ip+1)) + elseif st.expr isa QuoteNode + else + error("Unrecognised expression $(st.expr)") + end + elseif (brs = openbranches(block); length(brs) == 1 && !isreturn(brs[1]) + && !(brs[1].block == length(frame.ir.blocks))) + inferbranch!(inf, frame, b, f, brs[1]) else - error("Unrecognised expression $(st.expr)") - end - elseif (brs = openbranches(block); length(brs) == 1 && !isreturn(brs[1]) - && !(brs[1].block == length(frame.ir.blocks))) - inferbranch!(inf, frame, b, f, brs[1]) - else - for br in brs - if isreturn(br) - T = exprtype(block.ir, IRTools.returnvalue(block)) - _issubtype(T, frame.rettype) && return - frame.rettype = _union(frame.rettype, T) - foreach(loc -> push!(inf.queue, loc), frame.edges) - else - args = exprtype.((block.ir,), arguments(br)) - if blockargs!(IRTools.block(frame.ir, br.block), args) - push!(inf.queue, (frame, br.block, 0, 1)) + for br in brs + if isreturn(br) + T = exprtype(block.ir, IRTools.returnvalue(block)) + _issubtype(T, frame.rettype) && return + frame.rettype = _union(frame.rettype, T) + foreach(loc -> push!(inf.queue, loc), frame.edges) + else + args = exprtype.((block.ir,), arguments(br)) + if blockargs!(IRTools.block(frame.ir, br.block), args) + push!(inf.queue, (frame, br.block, 0, 1)) + end + end end - end end - end - return + return end function infer!(inf::Inference) - while !isempty(inf.queue) - step!(inf) - end - for (_, fr) in inf.frames - inline_bbs!(fr) - fr.ir |> IRTools.Inner.trimblocks! - end - return inf + while !isempty(inf.queue) + step!(inf) + end + for (_, fr) in inf.frames + inline_bbs!(fr) + fr.ir |> IRTools.Inner.trimblocks! + end + return inf end function Inference(fr::Frame, P) - q = WorkQueue{Any}() - push!(q, (fr, 1, 0, 1)) - Inference(Dict(argtypes(fr.ir)=>fr), q, IdDict(), P) + q = WorkQueue{Any}() + push!(q, (fr, 1, 0, 1)) + Inference(Dict(argtypes(fr.ir)=>fr), q, IdDict(), P) end function infer!(P, ir::IR, args...) - fr = frame(ir, args...) - inf = Inference(fr, P) - infer!(inf) + fr = frame(ir, args...) + inf = Inference(fr, P) + infer!(inf) end function return_type(ir::IR, args...) - fr = frame(copy(ir), args...) - inf = Inference(fr, Defaults()) - infer!(inf) - return fr.rettype + fr = frame(copy(ir), args...) + inf = Inference(fr, Defaults()) + infer!(inf) + return fr.rettype end diff --git a/src/lib/base.jl b/src/lib/base.jl index 57b714c..d179713 100644 --- a/src/lib/base.jl +++ b/src/lib/base.jl @@ -52,5 +52,4 @@ struct KwFunc{F} end @abstract Basic Core.kwfunc(::T) where T = Const(KwFunc{T}()) -instead(::Basic, args, ::AType{KwFunc{F}}, kw, f, xs...) where F = - args, (Core.kwftype(widen(f)), kw, f, xs...) +instead(::Basic, args, ::AType{KwFunc{F}}, kw, f, xs...) where F = (args, (Core.kwftype(widen(f)), kw, f, xs...)) From 3ee05028af21c07879a316f19b945711c72240e6 Mon Sep 17 00:00:00 2001 From: femtomc Date: Fri, 9 Oct 2020 22:22:08 -0400 Subject: [PATCH 3/4] Added QuoteNode fallthrough to step, and added unit test. --- Manifest.toml | 45 +++++++++++++++++++++++++++++++++++++++++++++ src/infer.jl | 2 +- src/lib/numeric.jl | 4 ++-- test/trace.jl | 12 ++++++------ 4 files changed, 54 insertions(+), 9 deletions(-) create mode 100644 Manifest.toml diff --git a/Manifest.toml b/Manifest.toml new file mode 100644 index 0000000..7ba5159 --- /dev/null +++ b/Manifest.toml @@ -0,0 +1,45 @@ +# This file is machine-generated - editing it directly is not advised + +[[Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[Distributed]] +deps = ["Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[IRTools]] +deps = ["InteractiveUtils", "MacroTools", "Test"] +git-tree-sha1 = "a8d88c05a23b44b4da6cf4fb5659e13ff95e0f47" +uuid = "7869d1d1-7146-5819-86e3-90919afe41df" +version = "0.4.1" + +[[InteractiveUtils]] +deps = ["Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" + +[[Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" + +[[MacroTools]] +deps = ["Markdown", "Random"] +git-tree-sha1 = "f7d2e3f654af75f01ec49be82c231c382214223a" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.5" + +[[Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[Random]] +deps = ["Serialization"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[Test]] +deps = ["Distributed", "InteractiveUtils", "Logging", "Random"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" diff --git a/src/infer.jl b/src/infer.jl index 37a6b7d..e9f7223 100644 --- a/src/infer.jl +++ b/src/infer.jl @@ -188,6 +188,7 @@ function step!(inf::Inference) if ip <= length(stmts) var = stmts[ip] st = block[var] + st.expr isa QuoteNode && return if isexpr(st.expr, :call) T = infercall!(inf, (frame, b, f, ip), block, st.expr) if T != Union{} @@ -196,7 +197,6 @@ function step!(inf::Inference) end elseif isexpr(st.expr, :inbounds) push!(inf.queue, (frame, b, f, ip+1)) - elseif st.expr isa QuoteNode else error("Unrecognised expression $(st.expr)") end diff --git a/src/lib/numeric.jl b/src/lib/numeric.jl index 84c1e22..80a4eec 100644 --- a/src/lib/numeric.jl +++ b/src/lib/numeric.jl @@ -7,8 +7,7 @@ struct Numeric end asin, asind, asinh, atan, atand, atanh, cbrt, conj, cos, cosd, cosh, cospi, cot, cotd, coth, csc, cscd, csch, deg2rad, exp, exp10, exp2, expm1, float, inv, log, log10, log1p, log2, rad2deg, sec, secd, sech, - sin, sind, sinh, sinpi, sqrt, tan, tand, tanh, transpose, trailing_zeros, - >>, <<, unsigned, rem, // + sin, sind, sinh, sinpi, sqrt, tan, tand, tanh, transpose, trailing_zeros, >>, <<, unsigned, rem, // @abstract Numeric rand() = Float64 @abstract Numeric randn() = Float64 @@ -16,3 +15,4 @@ struct Numeric end @abstract Numeric sum(xs::Array{T,N}; dims = :) where {T,N} = dims == Const(:) ? T : Array{T,N} + diff --git a/test/trace.jl b/test/trace.jl index 6f6906f..ce5d304 100644 --- a/test/trace.jl +++ b/test/trace.jl @@ -145,14 +145,14 @@ tr = @trace pow(2, 3) tr = @trace pow(::Int, ::Int) @test returntype(tr) == Int -function pow(x, n) - n == one(n) && return x - n <= zero(n) && return zero(x) - return x*pow(x, n-1) +function m(n) + for i in 1 : n + nothing + end end -tr = @trace pow(Float64, Int) -@test returntype(tr) == Float64 +tr = @trace m(::Int) +@test returntype(tr) == Const(nothing) function sumabs2(xs) s = zero(eltype(xs)) From 489bae603b4a171738f1c8d12259c5a01e3896a3 Mon Sep 17 00:00:00 2001 From: femtomc Date: Fri, 9 Oct 2020 22:23:09 -0400 Subject: [PATCH 4/4] Added QuoteNode fallthrough to step, and added unit test. --- .gitignore | 1 + Manifest.toml | 45 --------------------------------------------- 2 files changed, 1 insertion(+), 45 deletions(-) delete mode 100644 Manifest.toml diff --git a/.gitignore b/.gitignore index d287cd3..2ffbad6 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ debug +Manifest.toml diff --git a/Manifest.toml b/Manifest.toml deleted file mode 100644 index 7ba5159..0000000 --- a/Manifest.toml +++ /dev/null @@ -1,45 +0,0 @@ -# This file is machine-generated - editing it directly is not advised - -[[Base64]] -uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" - -[[Distributed]] -deps = ["Random", "Serialization", "Sockets"] -uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" - -[[IRTools]] -deps = ["InteractiveUtils", "MacroTools", "Test"] -git-tree-sha1 = "a8d88c05a23b44b4da6cf4fb5659e13ff95e0f47" -uuid = "7869d1d1-7146-5819-86e3-90919afe41df" -version = "0.4.1" - -[[InteractiveUtils]] -deps = ["Markdown"] -uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" - -[[Logging]] -uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" - -[[MacroTools]] -deps = ["Markdown", "Random"] -git-tree-sha1 = "f7d2e3f654af75f01ec49be82c231c382214223a" -uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" -version = "0.5.5" - -[[Markdown]] -deps = ["Base64"] -uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" - -[[Random]] -deps = ["Serialization"] -uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" - -[[Serialization]] -uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" - -[[Sockets]] -uuid = "6462fe0b-24de-5631-8697-dd941f90decc" - -[[Test]] -deps = ["Distributed", "InteractiveUtils", "Logging", "Random"] -uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40"