Skip to content

Commit

Permalink
set up a specific type to capture the 3-set data of codelocs
Browse files Browse the repository at this point in the history
  • Loading branch information
aviatesk committed Mar 19, 2024
1 parent eb05b4f commit 6afde4b
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 27 deletions.
13 changes: 7 additions & 6 deletions base/compiler/ssair/inlining.jl
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ function ir_prepare_inlining!(insert_node!::Inserter, inline_target::Union{IRCod
debuginfo = inline_target isa IRCode ? inline_target.debuginfo : inline_target.ir.debuginfo

linetable_offset = ir_inline_linetable!(debuginfo, di, mi)
topline = (inlined_at, linetable_offset, Int32(0))
topline = DebugCodeLoc(inlined_at, linetable_offset, Int32(0))
if should_insert_coverage(def.module, di)
insert_node!(NewInstruction(Expr(:code_coverage_effect), Nothing, topline))
end
Expand All @@ -340,8 +340,9 @@ function ir_prepare_inlining!(insert_node!::Inserter, inline_target::Union{IRCod
if def.is_for_opaque_closure
# Replace the first argument by a load of the capture environment
argexprs[1] = insert_node!(
NewInstruction(Expr(:call, GlobalRef(Core, :getfield), argexprs[1], QuoteNode(:captures)),
ir.argtypes[1], topline))
NewInstruction(
Expr(:call, GlobalRef(Core, :getfield), argexprs[1], QuoteNode(:captures)),
ir.argtypes[1], topline))
end
return SSASubstitute(mi, argexprs, spvals_ssa, (inlined_at, linetable_offset))
end
Expand Down Expand Up @@ -379,7 +380,7 @@ function ir_inline_item!(compact::IncrementalCompact, idx::Int, argexprs::Vector
# something better eventually.
inline_compact[idx′] = nothing
# alter the line number information for InsertBefore to point to the current instruction in the new linetable
inline_compact[SSAValue(idx′)][:line] = (ssa_substitute.inlined_at[1], ssa_substitute.inlined_at[2], Int32(lineidx))
inline_compact[SSAValue(idx′)][:line] = DebugCodeLoc(ssa_substitute.inlined_at[1], ssa_substitute.inlined_at[2], lineidx)
insert_node! = InsertBefore(inline_compact, SSAValue(idx′))
stmt′ = ssa_substitute_op!(insert_node!, inline_compact[SSAValue(idx′)], stmt′, ssa_substitute)
if isa(stmt′, ReturnNode)
Expand Down Expand Up @@ -411,7 +412,7 @@ function ir_inline_item!(compact::IncrementalCompact, idx::Int, argexprs::Vector
@assert isempty(inline_compact.perm) && isempty(inline_compact.pending_perm) "linetable not in canonical form (missing compact call)"
for ((lineidx, idx′), stmt′) in inline_compact
inline_compact[idx′] = nothing
inline_compact[SSAValue(idx′)][:line] = (ssa_substitute.inlined_at[1], ssa_substitute.inlined_at[2], Int32(lineidx))
inline_compact[SSAValue(idx′)][:line] = DebugCodeLoc(ssa_substitute.inlined_at[1], ssa_substitute.inlined_at[2], lineidx)
insert_node! = InsertBefore(inline_compact, SSAValue(idx′))
stmt′ = ssa_substitute_op!(insert_node!, inline_compact[SSAValue(idx′)], stmt′, ssa_substitute)
if isa(stmt′, ReturnNode)
Expand Down Expand Up @@ -449,7 +450,7 @@ function ir_inline_item!(compact::IncrementalCompact, idx::Int, argexprs::Vector
end

function fix_va_argexprs!(insert_node!::Inserter, inline_target::Union{IRCode, IncrementalCompact},
argexprs::Vector{Any}, nargs_def::Int, line_idx::NTuple{3,Int32})
argexprs::Vector{Any}, nargs_def::Int, line_idx::DebugCodeLoc)
newargexprs = argexprs[1:(nargs_def-1)]
tuple_call = Expr(:call, TOP_TUPLE)
tuple_typs = Any[]
Expand Down
54 changes: 38 additions & 16 deletions base/compiler/ssair/ir.jl
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ mutable struct DebugInfoStream
end
#DebugInfoStream(def::Union{MethodInstance,Nothing}, di::DebugInfo, nstmts::Int) =
# if debuginfo_file1(di.def) === debuginfo_file1(di.def)
# new(def, di.linetable, Core.svec(di.edges...), getdebugidx(di, 0),
# new(def, di.linetable, Core.svec(di.edges...), getdebugidx(di, 0)[1],
# ccall(:jl_uncompress_codelocs, Any, (Any, Int), di.codelocs, nstmts)::Vector{Int32})
# else
function DebugInfoStream(def::Union{MethodInstance,Nothing}, di::DebugInfo, nstmts::Int)
Expand All @@ -206,15 +206,37 @@ Core.DebugInfo(di::DebugInfoStream, nstmts::Int) =
Core.DebugInfo(something(di.def), di.linetable, Core.svec(di.edges...),
ccall(:jl_compress_codelocs, Any, (Int32, Any, Int), di.firstline, di.codelocs, nstmts)::String)

getdebugidx(debuginfo::Core.DebugInfo, pc::Int) = ccall(:jl_uncompress1_codeloc, NTuple{3,Int32}, (Any, Int), debuginfo.codelocs, pc)
struct DebugCodeLoc
line::Int32
edge::Int32
edge_line::Int32
end
function getindex(dcl::DebugCodeLoc, idx::Int)
if idx == 1
return dcl.line
elseif idx == 2
return dcl.edge
elseif idx == 3
return dcl.edge_line
else
throw(BoundsError(dcl, idx))
end
end
function iterate(dcl::DebugCodeLoc, i::Int=1)
i > 3 && return nothing
return getfield(dcl, i), i+1
end

getdebugidx(debuginfo::Core.DebugInfo, pc::Int) = DebugCodeLoc(
ccall(:jl_uncompress1_codeloc, NTuple{3,Int32}, (Any, Int), debuginfo.codelocs, pc)...)

function getdebugidx(debuginfo::DebugInfoStream, pc::Int)
if 3 <= 3pc <= length(debuginfo.codelocs)
return (debuginfo.codelocs[3pc - 2], debuginfo.codelocs[3pc - 1], debuginfo.codelocs[3pc - 0])
return DebugCodeLoc(debuginfo.codelocs[3pc - 2], debuginfo.codelocs[3pc - 1], debuginfo.codelocs[3pc - 0])
elseif pc == 0
return (Int32(debuginfo.firstline), Int32(0), Int32(0))
return DebugCodeLoc(debuginfo.firstline, 0, 0)
else
return (Int32(-1), Int32(0), Int32(0))
return DebugCodeLoc(-1, 0, 0)
end
end

Expand Down Expand Up @@ -310,15 +332,15 @@ Instruction(is::InstructionStream) = Instruction(is, add_new_idx!(is))
isdefined(node, fld) && return getfield(node, fld)
fldarray = getfield(getfield(node, :data), fld)
fldidx = getfield(node, :idx)
(fld === :line) && return (fldarray[3fldidx-2], fldarray[3fldidx-1], fldarray[3fldidx-0])
(fld === :line) && return DebugCodeLoc(fldarray[3fldidx-2], fldarray[3fldidx-1], fldarray[3fldidx-0])
return fldarray[fldidx]
end
@inline function setindex!(node::Instruction, @nospecialize(val), fld::Symbol)
(fld === :inst) && (fld = :stmt) # deprecated
fldarray = getfield(getfield(node, :data), fld)
fldidx = getfield(node, :idx)
if fld === :line
(fldarray[3fldidx-2], fldarray[3fldidx-1], fldarray[3fldidx-0]) = val::NTuple{3,Int32}
(fldarray[3fldidx-2], fldarray[3fldidx-1], fldarray[3fldidx-0]) = val::DebugCodeLoc
else
fldarray[fldidx] = val
end
Expand Down Expand Up @@ -370,31 +392,31 @@ struct NewInstruction
stmt::Any
type::Any
info::CallInfo
line::Union{NTuple{3,Int32},Nothing} # if nothing, copy the line from previous statement in the insertion location
line::Union{DebugCodeLoc,Nothing} # if nothing, copy the line from previous statement in the insertion location
flag::Union{UInt32,Nothing} # if nothing, IR flags will be recomputed on insertion
function NewInstruction(@nospecialize(stmt), @nospecialize(type), @nospecialize(info::CallInfo),
line::Union{NTuple{3,Int32},Int32,Nothing}, flag::Union{UInt32,Nothing})
line isa Int32 && (line = (line, zero(Int32), zero(Int32)))
line::Union{DebugCodeLoc,Int32,Nothing}, flag::Union{UInt32,Nothing})
line isa Int32 && (line = DebugCodeLoc(line, 0, 0))
return new(stmt, type, info, line, flag)
end
end
function NewInstruction(@nospecialize(stmt), @nospecialize(type), line::Union{NTuple{3,Int32},Int32,Nothing}=nothing)
function NewInstruction(@nospecialize(stmt), @nospecialize(type), line::Union{DebugCodeLoc,Int32,Nothing}=nothing)
return NewInstruction(stmt, type, NoCallInfo(), line, nothing)
end
@nospecialize
function NewInstruction(newinst::NewInstruction;
stmt::Any=newinst.stmt,
type::Any=newinst.type,
info::CallInfo=newinst.info,
line::Union{NTuple{3,Int32},Int32,Nothing}=newinst.line,
line::Union{DebugCodeLoc,Int32,Nothing}=newinst.line,
flag::Union{UInt32,Nothing}=newinst.flag)
return NewInstruction(stmt, type, info, line, flag)
end
function NewInstruction(inst::Instruction;
stmt::Any=inst[:stmt],
type::Any=inst[:type],
info::CallInfo=inst[:info],
line::Union{NTuple{3,Int32},Int32,Nothing}=inst[:line],
line::Union{DebugCodeLoc,Int32,Nothing}=inst[:line],
flag::Union{UInt32,Nothing}=inst[:flag])
return NewInstruction(stmt, type, info, line, flag)
end
Expand Down Expand Up @@ -939,7 +961,7 @@ function add_pending!(compact::IncrementalCompact, pos::Int, attach_after::Bool)
end

function inst_from_newinst!(node::Instruction, newinst::NewInstruction,
newline::NTuple{3,Int32}=newinst.line::NTuple{3,Int32}, newflag::UInt32=newinst.flag::UInt32)
newline::DebugCodeLoc=newinst.line::DebugCodeLoc, newflag::UInt32=newinst.flag::UInt32)
node[:stmt] = newinst.stmt
node[:type] = newinst.type
node[:info] = newinst.info
Expand Down Expand Up @@ -1029,7 +1051,7 @@ function maybe_reopen_bb!(compact)
end

function insert_node_here!(compact::IncrementalCompact, newinst::NewInstruction, reverse_affinity::Bool=false)
newline = newinst.line::NTuple{3,Int32}
newline = newinst.line::DebugCodeLoc
refinish = false
result_idx = compact.result_idx
result_bbs = compact.cfg_transform.result_bbs
Expand Down Expand Up @@ -1671,7 +1693,7 @@ function resize!(compact::IncrementalCompact, nnewnodes::Int)
return compact
end

const NoLineUpdate = (Int32(0), Int32(0), Int32(0))
const NoLineUpdate = DebugCodeLoc(0, 0, 0)

function finish_current_bb!(compact::IncrementalCompact, active_bb::Int,
old_result_idx::Int=compact.result_idx, unreachable::Bool=false)
Expand Down
11 changes: 6 additions & 5 deletions base/compiler/ssair/passes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1523,14 +1523,15 @@ function try_inline_finalizer!(ir::IRCode, argexprs::Vector{Any}, idx::Int,
ssa_rename = Vector{Any}(undef, length(src.stmts))
for idx′ = 1:length(src.stmts)
inst = src[SSAValue(idx′)]
stmt = inst[:stmt]
isa(stmt, ReturnNode) && continue
stmt = ssamap(stmt) do ssa::SSAValue
stmt = inst[:stmt]
isa(stmt, ReturnNode) && continue
stmt = ssamap(stmt) do ssa::SSAValue
ssa_rename[ssa.id]
end
stmt′ = ssa_substitute_op!(InsertBefore(ir, SSAValue(idx)), inst, stmt′, ssa_substitute)
stmt = ssa_substitute_op!(InsertBefore(ir, SSAValue(idx)), inst, stmt, ssa_substitute)
line = DebugCodeLoc(ssa_substitute.inlined_at[1], ssa_substitute.inlined_at[2], idx′)
ssa_rename[idx′] = insert_node!(ir, idx,
NewInstruction(inst; stmt=stmt′, line=(ssa_substitute.inlined_at[1], ssa_substitute.inlined_at[2], Int32(idx′))),
NewInstruction(inst; stmt, line),
attach_after)
end

Expand Down
2 changes: 2 additions & 0 deletions base/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2838,6 +2838,8 @@ module IRShow
Base.iterate(is::Compiler.InstructionStream, st::Int=1) = (st <= Compiler.length(is)) ? (is[st], st + 1) : nothing
Base.getindex(is::Compiler.InstructionStream, idx::Int) = Compiler.getindex(is, idx)
Base.getindex(node::Compiler.Instruction, fld::Symbol) = Compiler.getindex(node, fld)
Base.getindex(dcl::Compiler.DebugCodeLoc, idx::Int) = Compiler.getindex(dcl, idx)
Base.iterate(dcl::Compiler.DebugCodeLoc, s::Int=1) = Compiler.iterate(dcl, s)
Base.getindex(ir::IRCode, ssa::SSAValue) = Compiler.getindex(ir, ssa)
include("compiler/ssair/show.jl")

Expand Down
5 changes: 5 additions & 0 deletions doc/src/devdocs/ast.md
Original file line number Diff line number Diff line change
Expand Up @@ -844,3 +844,8 @@ end
depth also might have changed, though most callers should ignore that.
- (zero, non-zero, *) : no line number, just edges (usually because of macro-expansion into
top-level code)

`Core.Compiler` has a bunch of utility types and functions for handling this data.
The `Core.Compiler.DebugCodeLoc` object represents the 3 values. And there's a handy
utility function, `Core.Compiler.getdebugidx(debuginfo::Union{Core.DebugInfo,Core.Compiler.DebugInfoStream}, idx::Int)`,
that gives you the `DebugCodeLoc` matching a specific statement index (`idx`).
10 changes: 10 additions & 0 deletions test/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2694,3 +2694,13 @@ let lowered = Meta.lower(Main, Expr(:let, Expr(:block), Expr(:block, Expr(:tople
# Check that this gets printed as `_1 = 1` not `y = 1`
@test contains(sprint(show, ci), "_1 = 1")
end

# exercise DILineInfoPrinter
test_DILineInfoPrinter(x) = @inline sin(x)
test_DILineInfoPrinter(42) # ensure we have code instance cache for `test_DILineInfoPrinter(::Int)`
let io = IOContext(IOBuffer(), :color=>true)
mi = only(methods(test_DILineInfoPrinter, (Int,))).specializations
src = Core.Compiler._uncompressed_ir(mi.cache, mi.cache.inferred::String)
Base.IRShow.show_ir(io, src, Base.IRShow.IRShowConfig(Base.IRShow.DILineInfoPrinter(src.debuginfo, :var"unknown scope")));
Base.IRShow.show_ir(io, src, Base.IRShow.IRShowConfig(Base.IRShow.DILineInfoPrinter(src.debuginfo, :var"unknown scope", true)));
end

0 comments on commit 6afde4b

Please sign in to comment.