Skip to content

Support for Julia v1.12 #196

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 73 additions & 29 deletions src/bbcode.jl
Original file line number Diff line number Diff line change
Expand Up @@ -140,22 +140,44 @@ end

collect_stmts(bb::BBlock)::Vector{IDInstPair} = collect(zip(bb.inst_ids, bb.insts))

struct BBCode
blocks::Vector{BBlock}
argtypes::Vector{Any}
sptypes::Vector{CC.VarState}
linetable::Vector{Core.LineInfoNode}
meta::Vector{Expr}
end
@static if VERSION >= v"1.12-"
struct BBCode
blocks::Vector{BBlock}
argtypes::Vector{Any}
sptypes::Vector{CC.VarState}
debuginfo::CC.DebugInfoStream
meta::Vector{Expr}
valid_worlds::CC.WorldRange
end

function BBCode(ir::Union{IRCode,BBCode}, new_blocks::Vector{BBlock})
return BBCode(
new_blocks,
CC.copy(ir.argtypes),
CC.copy(ir.sptypes),
CC.copy(ir.linetable),
CC.copy(ir.meta),
)
function BBCode(ir::Union{IRCode,BBCode}, new_blocks::Vector{BBlock})
return BBCode(
new_blocks,
CC.copy(ir.argtypes),
CC.copy(ir.sptypes),
CC.copy(ir.debuginfo),
CC.copy(ir.meta),
ir.valid_worlds,
)
end
else
struct BBCode
blocks::Vector{BBlock}
argtypes::Vector{Any}
sptypes::Vector{CC.VarState}
linetable::Vector{Core.LineInfoNode}
meta::Vector{Expr}
end

function BBCode(ir::Union{IRCode,BBCode}, new_blocks::Vector{BBlock})
return BBCode(
new_blocks,
CC.copy(ir.argtypes),
CC.copy(ir.sptypes),
CC.copy(ir.linetable),
CC.copy(ir.meta),
)
end
end

# Makes use of the above outer constructor for `BBCode`.
Expand Down Expand Up @@ -346,20 +368,42 @@ function CC.IRCode(bb_code::BBCode)
insts = _ids_to_line_numbers(bb_code)
cfg = control_flow_graph(bb_code)
insts = _lines_to_blocks(insts, cfg)
return IRCode(
CC.InstructionStream(
map(x -> x.stmt, insts),
map(x -> x.type, insts),
map(x -> x.info, insts),
map(x -> x.line, insts),
map(x -> x.flag, insts),
),
cfg,
CC.copy(bb_code.linetable),
CC.copy(bb_code.argtypes),
CC.copy(bb_code.meta),
CC.copy(bb_code.sptypes),
)
@static if VERSION >= v"1.12-"
# See e.g. here for how the NTuple{3,Int}s get flattened for InstructionStream:
# https://github.com/JuliaLang/julia/blob/16a2bf0a3b106b03dda23b8c9478aab90ffda5e1/Compiler/src/ssair/ir.jl#L299
lines = map(x -> x.line, insts)
lines = collect(Iterators.flatten(lines))
return IRCode(
CC.InstructionStream(
map(x -> x.stmt, insts),
collect(Any, map(x -> x.type, insts)),
collect(CC.CallInfo, map(x -> x.info, insts)),
lines,
map(x -> x.flag, insts),
),
cfg,
CC.copy(bb_code.debuginfo),
CC.copy(bb_code.argtypes),
CC.copy(bb_code.meta),
CC.copy(bb_code.sptypes),
bb_code.valid_worlds,
)
else
return IRCode(
CC.InstructionStream(
map(x -> x.stmt, insts),
map(x -> x.type, insts),
map(x -> x.info, insts),
map(x -> x.line, insts),
map(x -> x.flag, insts),
),
cfg,
CC.copy(bb_code.linetable),
CC.copy(bb_code.argtypes),
CC.copy(bb_code.meta),
CC.copy(bb_code.sptypes),
)
end
end

function _lower_switch_statements(bb_code::BBCode)
Expand Down
28 changes: 25 additions & 3 deletions src/copyable_task.jl
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,11 @@ expression, otherwise `false`.
"""
function is_produce_stmt(x)::Bool
if Meta.isexpr(x, :invoke) && length(x.args) == 3 && x.args[1] isa Core.MethodInstance
# This branch is hit on Julia 1.11 and earlier.
return x.args[1].specTypes <: Tuple{typeof(produce),Any}
elseif Meta.isexpr(x, :invoke) && length(x.args) == 3 && x.args[1] isa Core.CodeInstance
# This branch is hit on Julia 1.12.
return x.args[1].def.specTypes <: Tuple{typeof(produce),Any}
elseif Meta.isexpr(x, :call) && length(x.args) == 2
return get_value(x.args[1]) === produce
else
Expand All @@ -400,7 +404,13 @@ function stmt_might_produce(x, ret_type::Type)::Bool

# Statement will terminate in the usual fashion, so _do_ bother recusing.
is_produce_stmt(x) && return true
Meta.isexpr(x, :invoke) && return might_produce(x.args[1].specTypes)
@static if VERSION >= v"1.12-"
# On Julia 1.12 x.args has CodeInstances rather than MethodInstances. We use .def
# to get the MethodInstances.
Meta.isexpr(x, :invoke) && return might_produce(x.args[1].def.specTypes)
else
Meta.isexpr(x, :invoke) && return might_produce(x.args[1].specTypes)
end
if Meta.isexpr(x, :call)
# This is a hack -- it's perfectly possible for `DataType` calls to produce in general.
f = get_function(x.args[1])
Expand Down Expand Up @@ -964,7 +974,13 @@ function derive_copyable_task_ir(ir::BBCode)::Tuple{BBCode,Tuple,Vector{Any}}

# Derive TapedTask for this statement.
(callable, callable_args) = if Meta.isexpr(stmt, :invoke)
sig = stmt.args[1].specTypes
@static if VERSION >= v"1.12-"
# On Julia 1.12 stmt.args has CodeInstances rather than
# MethodInstances. We use .def to get the MethodInstances.
sig = stmt.args[1].def.specTypes
else
sig = stmt.args[1].specTypes
end
v = Any[Any]
(LazyCallable{sig,callable_ret_type(sig, v)}(), stmt.args[2:end])
elseif Meta.isexpr(stmt, :call)
Expand Down Expand Up @@ -1079,7 +1095,13 @@ function derive_copyable_task_ir(ir::BBCode)::Tuple{BBCode,Tuple,Vector{Any}}
new_argtypes = vcat(typeof(refs), copy(ir.argtypes))

# Return BBCode and the `Ref`s.
new_ir = BBCode(new_bblocks, new_argtypes, ir.sptypes, ir.linetable, ir.meta)
@static if VERSION >= v"1.12-"
new_ir = BBCode(
new_bblocks, new_argtypes, ir.sptypes, ir.debuginfo, ir.meta, ir.valid_worlds
)
else
new_ir = BBCode(new_bblocks, new_argtypes, ir.sptypes, ir.linetable, ir.meta)
end
return new_ir, refs, possible_produce_types
end

Expand Down
6 changes: 5 additions & 1 deletion src/test_utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,11 @@ function (case::Testcase)()
end

for _ in iteration_results
@test count_allocs(consume, t) == 0
# TODO(mhauru) We seem to be causing more allocations than expected on
# v1.12, needs investigating.
@static if VERSION < v"1.12-"
@test count_allocs(consume, t) == 0
end
end
end
end
Expand Down
59 changes: 47 additions & 12 deletions src/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,11 @@ function optimise_ir!(ir::IRCode; show_ir=false, do_inline=true)

ir = CC.compact!(ir)
# CC.verify_ir(ir, true, false, CC.optimizer_lattice(local_interp))
CC.verify_linetable(ir.linetable, true)
@static if VERSION >= v"1.12-"
CC.verify_linetable(ir.debuginfo, div(length(ir.debuginfo.codelocs), 3), true)
else
CC.verify_linetable(ir.linetable, true)
end
if show_ir
println("Post-optimization")
display(ir)
Expand Down Expand Up @@ -96,13 +100,29 @@ end
# Run type inference and constant propagation on the ir. Credit to @oxinabox:
# https://gist.github.com/oxinabox/cdcffc1392f91a2f6d80b2524726d802#file-example-jl-L54
function __infer_ir!(ir, interp::CC.AbstractInterpreter, mi::CC.MethodInstance)
method_info = CC.MethodInfo(true, nothing) #=propagate_inbounds=#
min_world = world = get_inference_world(interp)
max_world = Base.get_world_counter()
irsv = CC.IRInterpretationState(
interp, method_info, ir, mi, ir.argtypes, world, min_world, max_world
)
rt = CC._ir_abstract_constant_propagation(interp, irsv)
# TODO(mhauru) Why is this line here? This function is no longer defined in 1.12
@static if VERSION >= v"1.12-"
nargs = length(ir.argtypes) - 1
# TODO(mhauru) How do we figure out isva? I don't think it's in ir or mi, see above
# prints.
isva = false
propagate_inbounds = true
spec_info = CC.SpecInfo(nargs, isva, propagate_inbounds, nothing)
min_world = world = get_inference_world(interp)
max_world = Base.get_world_counter()
irsv = CC.IRInterpretationState(
interp, spec_info, ir, mi, ir.argtypes, world, min_world, max_world
)
rt = CC.ir_abstract_constant_propagation(interp, irsv)
else
method_info = CC.MethodInfo(true, nothing) #=propagate_inbounds=#
min_world = world = get_inference_world(interp)
max_world = Base.get_world_counter()
irsv = CC.IRInterpretationState(
interp, method_info, ir, mi, ir.argtypes, world, min_world, max_world
)
rt = CC._ir_abstract_constant_propagation(interp, irsv)
end
return ir
end

Expand Down Expand Up @@ -168,13 +188,28 @@ function opaque_closure(
)
# This implementation is copied over directly from `Core.OpaqueClosure`.
ir = CC.copy(ir)
nargs = length(ir.argtypes) - 1
sig = Base.Experimental.compute_oc_signature(ir, nargs, isva)
@static if VERSION >= v"1.12-"
ir.debuginfo.def === nothing &&
(ir.debuginfo.def = :var"generated IR for OpaqueClosure")
# On v1.12 OpaqueClosure expects the first arg to be the environment.
ir.argtypes[1] = typeof(env)
end
nargtypes = length(ir.argtypes)
nargs = nargtypes - 1
@static if VERSION >= v"1.12-"
sig = CC.compute_oc_signature(ir, nargs, isva)
else
sig = Base.Experimental.compute_oc_signature(ir, nargs, isva)
end
src = ccall(:jl_new_code_info_uninit, Ref{CC.CodeInfo}, ())
src.slotnames = fill(:none, nargs + 1)
src.slotflags = fill(zero(UInt8), length(ir.argtypes))
src.slotnames = fill(:none, nargtypes)
src.slotflags = fill(zero(UInt8), nargtypes)
src.slottypes = copy(ir.argtypes)
src.rettype = ret_type
@static if VERSION >= v"1.12-"
src.isva = isva
src.nargs = UInt(nargs + 1)
end
src = CC.ir_to_codeinf!(src, ir)
return Base.Experimental.generate_opaque_closure(
sig, Union{}, ret_type, src, nargs, isva, env...; do_compile
Expand Down
Loading