Skip to content
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

WIP: a new serialization format for optimizing & executing lowered IR #309

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
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
2 changes: 2 additions & 0 deletions src/JuliaInterpreter.jl
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ include("interpret.jl")
include("builtins.jl")
include("optimize.jl")
include("commands.jl")
# include("serializer.jl")
# using .Serializer
include("breakpoints.jl")

function set_compiled_methods()
Expand Down
23 changes: 21 additions & 2 deletions src/breakpoints.jl
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,27 @@ function prepare_slotfunction(framecode::FrameCode, body::Union{Symbol,Expr})
for i = 1:length(slotnames)
slotname = framecode.src.slotnames[i]
qslotname = QuoteNode(slotname)
getexpr = :(something($dataname.locals[$dataname.last_reference[$qslotname]]))
push!(assignments, Expr(:(=), slotname, :(haskey($dataname.last_reference, $qslotname) ? $getexpr : $default)))
list = framecode.slotnamelists[slotname]
if length(list) == 1
maxexpr = :($dataname.last_reference[$(list[1])] > 0 ? $(list[1]) : 0)
else
maxcounter, maxidx = gensym("maxcounter"), gensym("maxidx")
maxexpr = quote
begin
$maxcounter, $maxidx = 0, 0
for l in $list
counter = $dataname.last_reference[l]
if counter > $maxcounter
$maxcounter, $maxidx = counter, l
end
end
$maxidx
end
end
end
maxexsym = gensym("slotid")
push!(assignments, :($maxexsym = $maxexpr))
push!(assignments, :($slotname = $maxexsym > 0 ? something($dataname.locals[$maxexsym]) : $default))
end
if ismeth
syms = sparam_syms(framecode.scope)
Expand Down
32 changes: 32 additions & 0 deletions src/builtins_serializer.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Builtins and intrinsics could be indexed by something smaller than Int32,
# but since the system uses Int32 let's just use FIndexT for indexing everything.

@enum BuiltinToken::FIndexT begin
tgetfield=FIndexT(1)
tegal
end

builtin_tokens = Dict(Core.getfield => tgetfield,
Core.:(===) => tegal)
const builtin = Any[]

intrinsic_token(f) = FIndexT(Core.bitcast(Int32, f))
const intrinsic = Any[]

function fill_ftables()
resize!(builtin, length(instances(BuiltinToken)))
for (f, tok) in builtin_tokens
builtin[Int(tok)] = f
end
for fname in names(Core.Intrinsics)
f = getfield(Core.Intrinsics, fname)
if f isa Core.IntrinsicFunction
tok = intrinsic_token(f)+1
if tok > length(intrinsic)
resize!(intrinsic, tok)
end
intrinsic[tok] = f
end
end
nothing
end
83 changes: 38 additions & 45 deletions src/construct.jl
Original file line number Diff line number Diff line change
Expand Up @@ -258,56 +258,49 @@ function prepare_call(@nospecialize(f), allargs; enter_generated = false)
end

function prepare_framedata(framecode, argvals::Vector{Any}, caller_will_catch_err::Bool=false)
src = framecode.src
slotnames = src.slotnames::SlotNamesType
ssavt = src.ssavaluetypes
ng, ns = isa(ssavt, Int) ? ssavt : length(ssavt::Vector{Any}), length(src.slotflags)
if length(junk) > 0
olddata = pop!(junk)
locals, ssavalues, sparams = olddata.locals, olddata.ssavalues, olddata.sparams
exception_frames, last_reference = olddata.exception_frames, olddata.last_reference
last_exception = olddata.last_exception
callargs = olddata.callargs
resize!(locals, ns)
fill!(locals, nothing)
resize!(ssavalues, ng)
# for check_isdefined to work properly, we need sparams to start out unassigned
resize!(sparams, 0)
empty!(exception_frames)
resize!(last_reference, ns)
last_exception[] = nothing
else
locals = Vector{Union{Nothing,Some{Any}}}(nothing, ns)
ssavalues = Vector{Any}(undef, ng)
sparams = Vector{Any}(undef, 0)
exception_frames = Int[]
last_reference = Vector{Int}(undef, ns)
callargs = Any[]
last_exception = Ref{Any}(nothing)
end
fill!(last_reference, 0)
if isa(framecode.scope, Method)
meth, src = framecode.scope::Method, framecode.src
slotnames = src.slotnames::SlotNamesType
ssavt = src.ssavaluetypes
ng = isa(ssavt, Int) ? ssavt : length(ssavt::Vector{Any})
meth = framecode.scope::Method
nargs, meth_nargs = length(argvals), Int(meth.nargs)
if length(junk) > 0
olddata = pop!(junk)
locals, ssavalues, sparams = olddata.locals, olddata.ssavalues, olddata.sparams
exception_frames, last_reference = olddata.exception_frames, olddata.last_reference
last_exception = olddata.last_exception
callargs = olddata.callargs
resize!(locals, length(src.slotflags))
resize!(ssavalues, ng)
# for check_isdefined to work properly, we need sparams to start out unassigned
resize!(sparams, 0)
empty!(exception_frames)
empty!(last_reference)
last_exception[] = nothing
else
locals = Vector{Union{Nothing,Some{Any}}}(undef, length(src.slotflags))
ssavalues = Vector{Any}(undef, ng)
sparams = Vector{Any}(undef, 0)
exception_frames = Int[]
last_reference = Dict{Symbol,Int}()
callargs = Any[]
last_exception = Ref{Any}(nothing)
end
for i = 1:meth_nargs
last_reference[slotnames[i]::Symbol] = i
if meth.isva && i == meth_nargs
locals[i] = nargs < i ? Some{Any}(()) : (let i=i; Some{Any}(ntuple(k->argvals[i+k-1], nargs-i+1)); end)
break
islastva = meth.isva && nargs >= meth_nargs
for i = 1:meth_nargs-islastva
if nargs >= i
locals[i], last_reference[i] = Some{Any}(argvals[i]), 1
else
locals[i] = Some{Any}(())
end
locals[i] = nargs >= i ? Some{Any}(argvals[i]) : Some{Any}(())
end
# add local variables initially undefined
for i = (meth_nargs+1):length(slotnames)
locals[i] = nothing
if islastva
locals[meth_nargs] = (let i=meth_nargs; Some{Any}(ntuple(k->argvals[i+k-1], nargs-i+1)); end)
last_reference[meth_nargs] = 1
end
else
src = framecode.src
locals = Vector{Union{Nothing,Some{Any}}}(undef, length(src.slotflags)) # src.slotflags is concretely typed, unlike slotnames
fill!(locals, nothing)
ssavalues = Vector{Any}(undef, length(src.code))
sparams = Any[]
exception_frames = Int[]
last_reference = Dict{Symbol,Int}()
callargs = Any[]
last_exception = Ref{Any}(nothing)
end
FrameData(locals, ssavalues, sparams, exception_frames, last_exception, caller_will_catch_err, last_reference, callargs)
end
Expand Down
4 changes: 2 additions & 2 deletions src/interpret.jl
Original file line number Diff line number Diff line change
Expand Up @@ -336,9 +336,9 @@ function do_assignment!(frame, @nospecialize(lhs), @nospecialize(rhs))
if isa(lhs, SSAValue)
data.ssavalues[lhs.id] = rhs
elseif isa(lhs, SlotNumber)
counter = (frame.assignment_counter += 1)
data.locals[lhs.id] = Some{Any}(rhs)
slotnames = code.src.slotnames::SlotNamesType
data.last_reference[slotnames[lhs.id]::Symbol] = lhs.id
data.last_reference[lhs.id] = counter
elseif isa(lhs, GlobalRef)
Core.eval(lhs.mod, :($(lhs.name) = $(QuoteNode(rhs))))
elseif isa(lhs, Symbol)
Expand Down
Loading