Skip to content

Commit

Permalink
update for 1.8 (#516)
Browse files Browse the repository at this point in the history
- it seems like `:ccall` preserves may now include `SlotNumber` objects,
  and so we need to update `build_compiled_call!` accordingly
- JuliaLang/julia#43671 increased the number of
  statements of code that involves assignment to a global variable
  • Loading branch information
aviatesk authored Feb 19, 2022
1 parent d172be1 commit 936f349
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 20 deletions.
27 changes: 15 additions & 12 deletions src/optimize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -268,9 +268,8 @@ function build_compiled_call!(stmt::Expr, fcall, code, idx, nargs::Int, sparams:
delete_idx = Int[]
if fcall === :ccall
cfunc, RetType, ArgType = lookup_stmt(code.code, stmt.args[1]), stmt.args[2], stmt.args[3]::SimpleVector
# The result of this is useful to have next to you when reading this code:
# f(x, y) = ccall(:jl_value_ptr, Ptr{Cvoid}, (Float32,Any), x, y)
# @code_lowered f(2, 3)
# delete cconvert and unsafe_convert calls and forward the original values, since
# the same conversions will be applied within the generated compiled variant of this :foreigncall anyway
args = []
for (atype, arg) in zip(ArgType, stmt.args[6:6+nargs-1])
if atype === Any
Expand All @@ -279,19 +278,23 @@ function build_compiled_call!(stmt::Expr, fcall, code, idx, nargs::Int, sparams:
if arg isa SSAValue
unsafe_convert_expr = code.code[arg.id]::Expr
push!(delete_idx, arg.id) # delete the unsafe_convert
cconvert_stmt = unsafe_convert_expr.args[3]::SSAValue
push!(delete_idx, cconvert_stmt.id) # delete the cconvert
cconvert_expr = code.code[cconvert_stmt.id]::Expr
push!(args, cconvert_expr.args[3])
cconvert_val = unsafe_convert_expr.args[3]
if isa(cconvert_val, SSAValue)
push!(delete_idx, cconvert_val.id) # delete the cconvert
newarg = (code.code[cconvert_val.id]::Expr).args[3]
push!(args, newarg)
else
@assert isa(cconvert_val, SlotNumber)
push!(args, cconvert_val)
end
elseif arg isa SlotNumber
index = findfirst(code.code) do expr
idx = findfirst(code.code) do expr
Meta.isexpr(expr, :(=)) || return false
lhs = expr.args[1]
return lhs isa SlotNumber && lhs.id === arg.id
end
index = index::Int
unsafe_convert_expr = code.code[index]::Expr
push!(delete_idx, index) # delete the unsafe_convert
end::Int
unsafe_convert_expr = code.code[idx]::Expr
push!(delete_idx, idx) # delete the unsafe_convert
push!(args, unsafe_convert_expr.args[2])
else
error("unexpected foreigncall argument type encountered: $(typeof(arg))")
Expand Down
18 changes: 12 additions & 6 deletions test/interpret.jl
Original file line number Diff line number Diff line change
Expand Up @@ -585,8 +585,11 @@ function call_cf()
ccall(cf[1], Int, (Int, Int), 1, 2)
end
@test (@interpret call_cf()) == call_cf()
frame = JuliaInterpreter.enter_call(call_cf)
@test frame.framecode.methodtables[2] == Compiled()
let mt = JuliaInterpreter.enter_call(call_cf).framecode.methodtables
@test any(1:length(mt)) do i
isassigned(mt, i) && mt[i] === Compiled()
end
end

# ccall with integer static parameter
f_N() = Array{Float64, 4}(undef, 1, 3, 2, 1)
Expand All @@ -597,8 +600,11 @@ f() = ccall((:clock, "libc"), Int32, ())
try @interpret f()
catch
end
frame = JuliaInterpreter.enter_call(f)
@test frame.framecode.methodtables[1] == Compiled()
let mt = JuliaInterpreter.enter_call(f).framecode.methodtables
@test any(1:length(mt)) do i
isassigned(mt, i) && mt[i] === Compiled()
end
end

# https://github.com/JuliaDebug/JuliaInterpreter.jl/issues/194
f() = Meta.lower(Main, Meta.parse("(a=1,0)"))
Expand Down Expand Up @@ -848,7 +854,7 @@ end
src = lwr.args[1]::Core.CodeInfo
frame = Frame(M, src; optimize=false)
@test length(frame.framecode.src.code) == length(src.code)
@test JuliaInterpreter.finish_and_return!(frame, true)
@test JuliaInterpreter.finish_and_return!(frame, true)

M = Module()
lwr = Meta.@lower M begin
Expand All @@ -868,7 +874,7 @@ end
src = lwr.args[1]::Core.CodeInfo
frame = Frame(M, src; optimize=false)
@test length(frame.framecode.src.code) == length(src.code)
@test JuliaInterpreter.finish_and_return!(frame, true)
@test JuliaInterpreter.finish_and_return!(frame, true)
end

iscallexpr(ex::Expr) = ex.head === :call
Expand Down
8 changes: 6 additions & 2 deletions test/limits.jl
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,11 @@ module EvalLimited end
insert!(ex.args, 1, LineNumberNode(1, Symbol("fake.jl")))
end
modexs = collect(ExprSplitter(EvalLimited, ex))
nstmts = 100 # enough to ensure it gets into the loop but doesn't finish
@static if isdefined(Core, :get_binding_type)
nstmts = 10*12 + 20 # 10 * 12 statements per iteration + α
else
nstmts = 9*12 + 20 # 10 * 9 statements per iteration + α
end
for (mod, ex) in modexs
frame = Frame(mod, ex)
@test isa(frame, Frame)
Expand All @@ -96,7 +100,7 @@ module EvalLimited end
isa(ret, Aborted) && (push!(aborts, ret); break)
end
end
@test 8 < EvalLimited.s < 50 # with Compiled(), 9 statements per iteration
@test 10 EvalLimited.s < 50
@test length(aborts) == 1
@test aborts[1].at.line (2, 3, 4, 5) # 2 corresponds to lowering of the for loop

Expand Down

0 comments on commit 936f349

Please sign in to comment.