diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index 2b736dbeff9d8..9244ee5f3f8ec 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -3304,6 +3304,10 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState) end if rt === Bottom ssavaluetypes[currpc] = Bottom + # Special case: Bottom-typed PhiNodes do not error (but must also be unused) + if isa(stmt, PhiNode) + continue + end @goto find_next_bb end if changes !== nothing diff --git a/base/compiler/optimize.jl b/base/compiler/optimize.jl index f634fc0bcb7e4..cbe80a65fc607 100644 --- a/base/compiler/optimize.jl +++ b/base/compiler/optimize.jl @@ -1086,7 +1086,7 @@ function convert_to_ircode(ci::CodeInfo, sv::OptimizationState) idx += 1 prevloc = codeloc end - if ssavaluetypes[idx] === Union{} && !(oldidx in sv.unreachable) + if ssavaluetypes[idx] === Union{} && !(oldidx in sv.unreachable) && !isa(code[idx], PhiNode) # We should have converted any must-throw terminators to an equivalent w/o control-flow edges @assert !isterminator(code[idx]) diff --git a/base/compiler/utilities.jl b/base/compiler/utilities.jl index 368395e714054..00c7ea40e3db9 100644 --- a/base/compiler/utilities.jl +++ b/base/compiler/utilities.jl @@ -415,15 +415,15 @@ function find_ssavalue_uses(body::Vector{Any}, nvals::Int) if isa(e, SSAValue) push!(uses[e.id], line) elseif isa(e, Expr) - find_ssavalue_uses(e, uses, line) + find_ssavalue_uses!(uses, e, line) elseif isa(e, PhiNode) - find_ssavalue_uses(e, uses, line) + find_ssavalue_uses!(uses, e, line) end end return uses end -function find_ssavalue_uses(e::Expr, uses::Vector{BitSet}, line::Int) +function find_ssavalue_uses!(uses::Vector{BitSet}, e::Expr, line::Int) head = e.head is_meta_expr_head(head) && return skiparg = (head === :(=)) @@ -433,13 +433,16 @@ function find_ssavalue_uses(e::Expr, uses::Vector{BitSet}, line::Int) elseif isa(a, SSAValue) push!(uses[a.id], line) elseif isa(a, Expr) - find_ssavalue_uses(a, uses, line) + find_ssavalue_uses!(uses, a, line) end end end -function find_ssavalue_uses(e::PhiNode, uses::Vector{BitSet}, line::Int) - for val in e.values +function find_ssavalue_uses!(uses::Vector{BitSet}, e::PhiNode, line::Int) + values = e.values + for i = 1:length(values) + isassigned(values, i) || continue + val = values[i] if isa(val, SSAValue) push!(uses[val.id], line) end diff --git a/test/compiler/interpreter_exec.jl b/test/compiler/interpreter_exec.jl index ce0704be15178..31f3f510cf4a2 100644 --- a/test/compiler/interpreter_exec.jl +++ b/test/compiler/interpreter_exec.jl @@ -20,13 +20,18 @@ let m = Meta.@lower 1 + 1 ReturnNode(SSAValue(6)), ] nstmts = length(src.code) - src.ssavaluetypes = Any[ Any for _ = 1:nstmts ] + src.ssavaluetypes = nstmts src.ssaflags = fill(UInt8(0x00), nstmts) src.codelocs = fill(Int32(1), nstmts) - src.inferred = true + @test !src.inferred Core.Compiler.verify_ir(Core.Compiler.inflate_ir(src)) global test29262 = true @test :a === @eval $m + compile_mode = @ccall jl_get_module_compile(@__MODULE__()::Module)::Cint + if compile_mode == 3 + # implies `Base.Experimental.@compiler_options compile=min` + @test !src.inferred + end global test29262 = false @test :b === @eval $m end @@ -61,13 +66,19 @@ let m = Meta.@lower 1 + 1 ReturnNode(SSAValue(18)), ] nstmts = length(src.code) - src.ssavaluetypes = Any[ Any for _ = 1:nstmts ] + src.ssavaluetypes = nstmts src.ssaflags = fill(UInt8(0x00), nstmts) src.codelocs = fill(Int32(1), nstmts) - src.inferred = true + @test !src.inferred Core.Compiler.verify_ir(Core.Compiler.inflate_ir(src)) global test29262 = true @test (:b, :a, :c, :c) === @eval $m + compile_mode = @ccall jl_get_module_compile(@__MODULE__()::Module)::Cint + if compile_mode == 3 + # implies `Base.Experimental.@compiler_options compile=min` + @test !src.inferred + end + src.ssavaluetypes = nstmts global test29262 = false @test (:b, :a, :c, :b) === @eval $m end @@ -98,27 +109,18 @@ let m = Meta.@lower 1 + 1 ReturnNode(SSAValue(11)), ] nstmts = length(src.code) - src.ssavaluetypes = Any[ Any for _ = 1:nstmts ] + src.ssavaluetypes = nstmts src.ssaflags = fill(UInt8(0x00), nstmts) src.codelocs = fill(Int32(1), nstmts) - src.inferred = true + @test !src.inferred Core.Compiler.verify_ir(Core.Compiler.inflate_ir(src)) global test29262 = true @test :a === @eval $m + compile_mode = @ccall jl_get_module_compile(@__MODULE__()::Module)::Cint + if compile_mode == 3 + # implies `Base.Experimental.@compiler_options compile=min` + @test !src.inferred + end global test29262 = false @test :b === @eval $m end - -# https://github.com/JuliaLang/julia/issues/47065 -# `Core.Compiler.sort!` should be able to handle a big list -let n = 1000 - ex = :(return 1) - for _ in 1:n - ex = :(rand() < .1 && $(ex)) - end - @eval global function f_1000_blocks() - $ex - return 0 - end -end -@test f_1000_blocks() == 0 diff --git a/test/compiler/irpasses.jl b/test/compiler/irpasses.jl index 2e14fdb8d3013..9345c2e26db33 100644 --- a/test/compiler/irpasses.jl +++ b/test/compiler/irpasses.jl @@ -1787,3 +1787,17 @@ let code = Any[ @test !any(iscall((ir, getfield)), ir.stmts.stmt) @test length(ir.cfg.blocks[end].stmts) == 1 end + +# https://github.com/JuliaLang/julia/issues/47065 +# `Core.Compiler.sort!` should be able to handle a big list +let n = 1000 + ex = :(return 1) + for _ in 1:n + ex = :(rand() < .1 && $(ex)) + end + @eval global function f_1000_blocks() + $ex + return 0 + end +end +@test f_1000_blocks() == 0 diff --git a/test/compiler/ssair.jl b/test/compiler/ssair.jl index bab11d3ead522..3a90ee6308d53 100644 --- a/test/compiler/ssair.jl +++ b/test/compiler/ssair.jl @@ -92,11 +92,15 @@ let cfg = CFG(BasicBlock[ end end -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 +# test code execution with the default compile-mode +module CompilerExecTest +include("interpreter_exec.jl") +end + +# test code execution with the interpreter mode (compile=min) +module InterpreterExecTest +Base.Experimental.@compiler_options compile=min +include("interpreter_exec.jl") end # PR #32145