Skip to content

Commit 82b7584

Browse files
committed
update for 1.8
- 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
1 parent d172be1 commit 82b7584

File tree

3 files changed

+33
-20
lines changed

3 files changed

+33
-20
lines changed

src/optimize.jl

+15-12
Original file line numberDiff line numberDiff line change
@@ -268,9 +268,8 @@ function build_compiled_call!(stmt::Expr, fcall, code, idx, nargs::Int, sparams:
268268
delete_idx = Int[]
269269
if fcall === :ccall
270270
cfunc, RetType, ArgType = lookup_stmt(code.code, stmt.args[1]), stmt.args[2], stmt.args[3]::SimpleVector
271-
# The result of this is useful to have next to you when reading this code:
272-
# f(x, y) = ccall(:jl_value_ptr, Ptr{Cvoid}, (Float32,Any), x, y)
273-
# @code_lowered f(2, 3)
271+
# delete cconvert and unsafe_convert calls and forward the original values, since
272+
# the same conversions will be applied within the generated compiled variant of this :foreigncall anyway
274273
args = []
275274
for (atype, arg) in zip(ArgType, stmt.args[6:6+nargs-1])
276275
if atype === Any
@@ -279,19 +278,23 @@ function build_compiled_call!(stmt::Expr, fcall, code, idx, nargs::Int, sparams:
279278
if arg isa SSAValue
280279
unsafe_convert_expr = code.code[arg.id]::Expr
281280
push!(delete_idx, arg.id) # delete the unsafe_convert
282-
cconvert_stmt = unsafe_convert_expr.args[3]::SSAValue
283-
push!(delete_idx, cconvert_stmt.id) # delete the cconvert
284-
cconvert_expr = code.code[cconvert_stmt.id]::Expr
285-
push!(args, cconvert_expr.args[3])
281+
cconvert_val = unsafe_convert_expr.args[3]
282+
if isa(cconvert_val, SSAValue)
283+
push!(delete_idx, cconvert_val.id) # delete the cconvert
284+
newarg = (code.code[cconvert_val.id]::Expr).args[3]
285+
push!(args, newarg)
286+
else
287+
@assert isa(cconvert_val, SlotNumber)
288+
push!(args, cconvert_val)
289+
end
286290
elseif arg isa SlotNumber
287-
index = findfirst(code.code) do expr
291+
idx = findfirst(code.code) do expr
288292
Meta.isexpr(expr, :(=)) || return false
289293
lhs = expr.args[1]
290294
return lhs isa SlotNumber && lhs.id === arg.id
291-
end
292-
index = index::Int
293-
unsafe_convert_expr = code.code[index]::Expr
294-
push!(delete_idx, index) # delete the unsafe_convert
295+
end::Int
296+
unsafe_convert_expr = code.code[idx]::Expr
297+
push!(delete_idx, idx) # delete the unsafe_convert
295298
push!(args, unsafe_convert_expr.args[2])
296299
else
297300
error("unexpected foreigncall argument type encountered: $(typeof(arg))")

test/interpret.jl

+12-6
Original file line numberDiff line numberDiff line change
@@ -585,8 +585,11 @@ function call_cf()
585585
ccall(cf[1], Int, (Int, Int), 1, 2)
586586
end
587587
@test (@interpret call_cf()) == call_cf()
588-
frame = JuliaInterpreter.enter_call(call_cf)
589-
@test frame.framecode.methodtables[2] == Compiled()
588+
let mt = JuliaInterpreter.enter_call(call_cf).framecode.methodtables
589+
@test any(1:length(mt)) do i
590+
isassigned(mt, i) && mt[i] === Compiled()
591+
end
592+
end
590593

591594
# ccall with integer static parameter
592595
f_N() = Array{Float64, 4}(undef, 1, 3, 2, 1)
@@ -597,8 +600,11 @@ f() = ccall((:clock, "libc"), Int32, ())
597600
try @interpret f()
598601
catch
599602
end
600-
frame = JuliaInterpreter.enter_call(f)
601-
@test frame.framecode.methodtables[1] == Compiled()
603+
let mt = JuliaInterpreter.enter_call(f).framecode.methodtables
604+
@test any(1:length(mt)) do i
605+
isassigned(mt, i) && mt[i] === Compiled()
606+
end
607+
end
602608

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

853859
M = Module()
854860
lwr = Meta.@lower M begin
@@ -868,7 +874,7 @@ end
868874
src = lwr.args[1]::Core.CodeInfo
869875
frame = Frame(M, src; optimize=false)
870876
@test length(frame.framecode.src.code) == length(src.code)
871-
@test JuliaInterpreter.finish_and_return!(frame, true)
877+
@test JuliaInterpreter.finish_and_return!(frame, true)
872878
end
873879

874880
iscallexpr(ex::Expr) = ex.head === :call

test/limits.jl

+6-2
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,11 @@ module EvalLimited end
8585
insert!(ex.args, 1, LineNumberNode(1, Symbol("fake.jl")))
8686
end
8787
modexs = collect(ExprSplitter(EvalLimited, ex))
88-
nstmts = 100 # enough to ensure it gets into the loop but doesn't finish
88+
@static if isdefined(Core, :get_binding_type)
89+
nstmts = 10*12 + 20 # 10 * 12 statements per iteration + α
90+
else
91+
nstmts = 9*12 + 20 # 10 * 9 statements per iteration + α
92+
end
8993
for (mod, ex) in modexs
9094
frame = Frame(mod, ex)
9195
@test isa(frame, Frame)
@@ -96,7 +100,7 @@ module EvalLimited end
96100
isa(ret, Aborted) && (push!(aborts, ret); break)
97101
end
98102
end
99-
@test 8 < EvalLimited.s < 50 # with Compiled(), 9 statements per iteration
103+
@test 10 EvalLimited.s < 50
100104
@test length(aborts) == 1
101105
@test aborts[1].at.line (2, 3, 4, 5) # 2 corresponds to lowering of the for loop
102106

0 commit comments

Comments
 (0)