Skip to content

Commit dd1aa0d

Browse files
committed
adapt to upstream linetable change
`Core.Compiler.LineInfoNode` was removed in JuliaLang/julia#52415 but kept in `Core` for serializer compatibility reasons (see https://github.com/JuliaLang/julia/blob/e07c0f1ddbfc89ad1ac4dda7246d8ed5d0d57c19/base/boot.jl#L491). Linetable representation in Julia IR has been changed to be more compact. This commit updates IRTools to decode and generate valid debug information according to these changes. Adaptation for IRTools is relatively straightforward in the sense that IRTools operates on untyped IR which does not contains inline statements. However, IRTools contains an inlining pass but it did not account for linetable information previously. In this change, I have made the choice to use the same line for all inlined statements. This can be further improved in the future.
1 parent 538a96d commit dd1aa0d

File tree

4 files changed

+72
-11
lines changed

4 files changed

+72
-11
lines changed

src/ir/ir.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using Core.Compiler: LineInfoNode
1+
using Base.IRShow: LineInfoNode
22
import Base: push!, insert!, getindex, setindex!, iterate, length
33

44
# We have our own versions of these in order to

src/ir/wrap.jl

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@ end
1414

1515
unvars(ex) = prewalk(x -> x isa Variable ? SSAValue(x.id) : x, ex)
1616

17+
18+
@static if VERSION v"1.12.0-DEV.173"
19+
addline!(lines, li) = push!(lines, li, Int32(0), Int32(0))
20+
else
21+
addline!(lines, li) = push!(lines, li)
22+
end
23+
1724
function IRCode(ir::IR)
1825
defs = Dict()
1926
stmts, types, lines = [], [], Int32[]
@@ -34,7 +41,7 @@ function IRCode(ir::IR)
3441
end
3542
push!(stmts, ex)
3643
push!(types, st.type)
37-
push!(lines, st.line)
44+
addline!(lines, st.line)
3845
end
3946
for br in BasicBlock(b).branches
4047
if IRTools.isreturn(br)
@@ -52,7 +59,7 @@ function IRCode(ir::IR)
5259
cond = get(defs, br.condition, br.condition) |> unvars
5360
push!(stmts, GotoIfNot(cond, br.block))
5461
end
55-
push!(types, Any); push!(lines, 0)
62+
push!(types, Any); addline!(lines, Int32(0))
5663
end
5764
push!(index, length(stmts)+1)
5865
end
@@ -61,7 +68,8 @@ function IRCode(ir::IR)
6168
preds = map.(x -> x.id, IRTools.predecessors.(IRTools.blocks(ir)))
6269
bs = Core.Compiler.BasicBlock.(ranges, preds, succs)
6370
cfg = CFG(bs, index)
64-
flags = [0x00 for _ in stmts]
71+
72+
flags = UInt32[0x00 for _ in stmts]
6573
sps = VERSION > v"1.2-" ? (VERSION >= v"1.10.0-DEV.552" ? Core.Compiler.VarState[] : []) : Core.svec()
6674

6775
@static if VERSION > v"1.6-"
@@ -72,7 +80,36 @@ function IRCode(ir::IR)
7280
end
7381
stmts = InstructionStream(stmts, types, stmtinfo, lines, flags)
7482
meta = @static VERSION < v"1.9.0-DEV.472" ? [] : Expr[]
75-
IRCode(stmts, cfg, ir.lines, ir.blocks[1].argtypes, meta, sps)
83+
@static if VERSION v"1.12.0-DEV.173"
84+
nlocs = length(types)
85+
codelocs = fill(Int32(0), 3nlocs)
86+
87+
if !isempty(ir.lines)
88+
LI = first(ir.lines)
89+
topfile, topline = LI.file, LI.line
90+
91+
for i in 1:nlocs
92+
lineidx = lines[3i - 2]
93+
if lineidx == 0
94+
continue
95+
end
96+
# TODO: support inlining, see passes/inline.jl
97+
@assert LI.file === topfile && LI.inlined_at == 0
98+
LI = ir.lines[lineidx]
99+
codelocs[3i - 2] = LI.line
100+
end
101+
else
102+
topline = Int32(1)
103+
end
104+
codelocs = @ccall jl_compress_codelocs(topline::Int32, codelocs::Any, nlocs::Csize_t)::Any
105+
106+
debuginfo = Core.Compiler.DebugInfoStream(lines)
107+
debuginfo.def = ir.meta isa Meta ? ir.meta.instance : :var"n/a"
108+
debuginfo.linetable = Core.DebugInfo(debuginfo.def, nothing, Core.svec(), codelocs)
109+
IRCode(stmts, cfg, debuginfo, ir.blocks[1].argtypes, meta, sps)
110+
else
111+
IRCode(stmts, cfg, ir.lines, ir.blocks[1].argtypes, meta, sps)
112+
end
76113
else
77114
IRCode(stmts, types, lines, flags, cfg, ir.lines, ir.blocks[1].argtypes, [], sps)
78115
end
@@ -118,7 +155,26 @@ slotname(ci, s) = Symbol(:_, s.id)
118155

119156
function IR(ci::CodeInfo, nargs::Integer; meta = nothing)
120157
bs = blockstarts(ci)
121-
ir = IR(Core.LineInfoNode[ci.linetable...], meta = meta)
158+
codelocs, linetable = @static if VERSION v"1.12.0-DEV.173"
159+
def = isnothing(meta) ? :var"n/a" : meta.instance
160+
N = length(ci.code)
161+
codelocs = fill(0, N)
162+
linetable = Base.IRShow.LineInfoNode[]
163+
164+
# NOTE: we could be faster about decoding here and support inlining?
165+
for pc in 1:N
166+
LI = Base.IRShow.buildLineInfoNode(ci.debuginfo, def, pc)
167+
if !isempty(LI)
168+
push!(linetable, first(LI))
169+
codelocs[pc] = length(linetable)
170+
end
171+
end
172+
173+
codelocs, linetable
174+
else
175+
ci.codelocs, Core.LineInfoNode[ci.linetable...]
176+
end
177+
ir = IR(linetable, meta = meta)
122178
_rename = Dict()
123179
rename(ex) = prewalk(ex) do x
124180
haskey(_rename, x) && return _rename[x]
@@ -151,7 +207,7 @@ function IR(ci::CodeInfo, nargs::Integer; meta = nothing)
151207
elseif isreturn(ex)
152208
return!(ir, rename(retval(ex)))
153209
else
154-
_rename[Core.SSAValue(i)] = push!(ir, IRTools.stmt(rename(ex), line = ci.codelocs[i]))
210+
_rename[Core.SSAValue(i)] = push!(ir, IRTools.stmt(rename(ex), line = codelocs[i]))
155211
end
156212
end
157213
return ir

src/passes/inline.jl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@ function fixup_blocks!(ir, n)
88
end
99
end
1010

11-
function inlinehere!(ir, source, args...)
11+
function inlinehere!(ir, line, source, args...)
1212
source = merge_returns!(copy(source)) # TODO preserve type info
1313
offset = length(blocks(ir.to))-1
1414
env = Dict()
1515
retvalue = nothing
1616
rename(x::Variable) = env[x]
1717
rename(x::Expr) = Expr(x.head, rename.(x.args)...)
18-
rename(x::Statement) = stmt(x, expr = rename(x.expr))
18+
rename(x::Statement) = stmt(x; expr=rename(x.expr), line=line)
1919
rename(x) = x
2020
for (name, arg) in zip(arguments(source), args)
2121
env[name] = arg
@@ -78,9 +78,12 @@ function inline(ir::IR, loc::Variable, source::IR)
7878
if v === loc
7979
startblock = length(blocks(pr.to))
8080
fixup_blocks!(pr.to, length(blocks(source)))
81+
# TODO: when inlining, we set all statements from source
82+
# .... at the line from loc. Ideally, we use the `inlined_at` field.
83+
line = ir[loc].line
8184
ex = ir[loc].expr
8285
delete!(pr, v)
83-
v′ = inlinehere!(pr, source, ex.args...)
86+
v′ = inlinehere!(pr, line, source, ex.args...)
8487
substitute!(pr, v, substitute(pr, v′))
8588
end
8689
end

src/reflection/utils.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,9 @@ end
156156

157157
function update!(ci::CodeInfo, ir::Core.Compiler.IRCode)
158158
replace_code_newstyle!(ci, ir, length(ir.argtypes))
159-
ci.inferred = false
159+
@static if VERSION < v"1.12.0-DEV.15"
160+
ci.inferred = false
161+
end
160162
ci.ssavaluetypes = length(ci.code)
161163
slots!(ci)
162164
fill!(ci.slotflags, 0)

0 commit comments

Comments
 (0)