Skip to content

Commit

Permalink
interpreter: in phi node, val may be explicitly null
Browse files Browse the repository at this point in the history
previously, we only handled the case where it was implicitly null
  • Loading branch information
vtjnash committed Nov 2, 2018
1 parent 2d8e610 commit ceec71e
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 26 deletions.
29 changes: 17 additions & 12 deletions base/compiler/typeinfer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,7 @@ end

# compute (and cache) an inferred AST and return type
function typeinf_ext(linfo::MethodInstance, params::Params)
method = linfo.def::Method
for i = 1:2 # test-and-lock-and-test
i == 2 && ccall(:jl_typeinf_begin, Cvoid, ())
if isdefined(linfo, :inferred)
Expand All @@ -538,7 +539,6 @@ function typeinf_ext(linfo::MethodInstance, params::Params)
if min_world(linfo) <= params.world <= max_world(linfo)
inf = linfo.inferred
if invoke_api(linfo) == 2
method = linfo.def::Method
tree = ccall(:jl_new_code_info_uninit, Ref{CodeInfo}, ())
tree.code = Any[ Expr(:return, quoted(linfo.inferred_const)) ]
tree.method_for_inference_limit_heuristics = nothing
Expand Down Expand Up @@ -610,17 +610,22 @@ end
# method lambda - infer this specialization via the method cache
return typeinf_ext(linfo, Params(world))
else
# toplevel lambda - infer directly
ccall(:jl_typeinf_begin, Cvoid, ())
result = InferenceResult(linfo)
frame = InferenceState(result, linfo.inferred::CodeInfo,
#=cached=#true, Params(world))
typeinf(frame)
ccall(:jl_typeinf_end, Cvoid, ())
@assert frame.inferred # TODO: deal with this better
@assert frame.linfo === linfo
linfo.rettype = widenconst(frame.bestguess)
return svec(linfo, frame.src)
src = linfo.inferred::CodeInfo
if !src.inferred
# toplevel lambda - infer directly
ccall(:jl_typeinf_begin, Cvoid, ())
if !src.inferred
result = InferenceResult(linfo)
frame = InferenceState(result, src, #=cached=#true, Params(world))
typeinf(frame)
@assert frame.inferred # TODO: deal with this better
@assert frame.linfo === linfo
linfo.rettype = widenconst(frame.bestguess)
src = frame.src
end
ccall(:jl_typeinf_end, Cvoid, ())
end
return svec(linfo, src)
end
end

Expand Down
6 changes: 4 additions & 2 deletions src/interpreter.c
Original file line number Diff line number Diff line change
Expand Up @@ -568,10 +568,12 @@ SECT_INTERP static size_t eval_phi(jl_array_t *stmts, interpreter_state *s, size
nphi -= n_oldphi;
}
if (edge != -1) {
// if edges list doesn't contain last branch, this value should be unused.
// if edges list doesn't contain last branch, or the value is explicitly undefined
// then this value should be unused.
jl_array_t *values = (jl_array_t*)jl_fieldref_noalloc(e, 1);
val = jl_array_ptr_ref(values, edge);
val = eval_value(val, s);
if (val)
val = eval_value(val, s);
}
phis[i] = val;
}
Expand Down
28 changes: 17 additions & 11 deletions test/compiler/interpreter_exec.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ let m = Meta.@lower 1 + 1
Expr(:return, Core.SSAValue(6)),
]
nstmts = length(src.code)
src.ssavaluetypes = nstmts
src.ssavaluetypes = Any[ Any for _ = 1:nstmts ]
src.codelocs = fill(Int32(1), nstmts)
src.inferred = true
Core.Compiler.verify_ir(Core.Compiler.inflate_ir(src))
global test29262 = true
@test :a === @eval $m
Expand All @@ -38,25 +39,29 @@ let m = Meta.@lower 1 + 1
QuoteNode(:c),
GlobalRef(@__MODULE__, :test29262),
# block 2
Core.PhiNode(Any[4, 13], Any[false, true]), # false, true
Core.PhiNode(Any[4, 13], Any[Core.SSAValue(1), Core.SSAValue(2)]), # :a, :b
Core.PhiNode(Any[4, 13], Any[Core.SSAValue(3), Core.SSAValue(6)]), # :c, :a
Core.PhiNode(Any[13], Any[Core.SSAValue(7)]), # NULL, :c
Core.PhiNode(Any[4, 16], Any[false, true]), # false, true
Core.PhiNode(Any[4, 16], Any[Core.SSAValue(1), Core.SSAValue(2)]), # :a, :b
Core.PhiNode(Any[4, 16], Any[Core.SSAValue(3), Core.SSAValue(6)]), # :c, :a
Core.PhiNode(Any[16], Any[Core.SSAValue(7)]), # NULL, :c
# block 3
Core.PhiNode(Any[], Any[]), # NULL, NULL
Core.PhiNode(Any[14, 8], Any[true, Core.SSAValue(4)]), # test29262, test29262, [true]
Core.PhiNode(Any[14, 8], Any[Core.SSAValue(2), Core.SSAValue(8)]), # NULL, :c, [:b]
Core.PhiNode(Any[17, 8], Any[true, Core.SSAValue(4)]), # test29262, test29262, [true]
Core.PhiNode(Any[17], Vector{Any}(undef, 1)), # NULL, NULL
Core.PhiNode(Any[8], Vector{Any}(undef, 1)), # NULL, NULL
Core.PhiNode(Any[], Any[]), # NULL, NULL
Core.PhiNode(Any[17, 8], Any[Core.SSAValue(2), Core.SSAValue(8)]), # NULL, :c, [:b]
Core.PhiNode(Any[], Any[]), # NULL, NULL
Expr(:gotoifnot, Core.SSAValue(5), 5),
# block 4
Expr(:gotoifnot, Core.SSAValue(10), 9),
# block 5
Expr(:call, GlobalRef(Core, :tuple), Core.SSAValue(6), Core.SSAValue(7), Core.SSAValue(8), Core.SSAValue(11)),
Expr(:return, Core.SSAValue(15)),
Expr(:call, GlobalRef(Core, :tuple), Core.SSAValue(6), Core.SSAValue(7), Core.SSAValue(8), Core.SSAValue(14)),
Expr(:return, Core.SSAValue(18)),
]
nstmts = length(src.code)
src.ssavaluetypes = nstmts
src.ssavaluetypes = Any[ Any for _ = 1:nstmts ]
src.codelocs = fill(Int32(1), nstmts)
src.inferred = true
Core.Compiler.verify_ir(Core.Compiler.inflate_ir(src))
global test29262 = true
@test (:b, :a, :c, :c) === @eval $m
Expand Down Expand Up @@ -91,8 +96,9 @@ let m = Meta.@lower 1 + 1
Expr(:return, Core.SSAValue(11)),
]
nstmts = length(src.code)
src.ssavaluetypes = nstmts
src.ssavaluetypes = Any[ Any for _ = 1:nstmts ]
src.codelocs = fill(Int32(1), nstmts)
src.inferred = true
Core.Compiler.verify_ir(Core.Compiler.inflate_ir(src))
global test29262 = true
@test :a === @eval $m
Expand Down
3 changes: 2 additions & 1 deletion test/compiler/ssair.jl
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ let
# XXX: missing @test
end

let cmd = `$(Base.julia_cmd()) --compile=min interpreter_exec.jl`
for compile in ("min", "yes")
cmd = `$(Base.julia_cmd()) --compile=$compile interpreter_exec.jl`
if !success(pipeline(Cmd(cmd, dir=@__DIR__); stdout=stdout, stderr=stderr))
error("Interpreter test failed, cmd : $cmd")
end
Expand Down

0 comments on commit ceec71e

Please sign in to comment.