Skip to content

Commit 6f6296d

Browse files
Merge pull request #122 from FluxML/pb/lineinfonode
Adapt to nightly linetable changes
2 parents 538a96d + 1f0968c commit 6f6296d

File tree

4 files changed

+94
-12
lines changed

4 files changed

+94
-12
lines changed

src/ir/ir.jl

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,22 @@
1-
using Core.Compiler: LineInfoNode
21
import Base: push!, insert!, getindex, setindex!, iterate, length
32

43
# We have our own versions of these in order to
54
# (1) be more robust to Base IR changes, and
65
# (2) make sure that mistakes/bugs do not cause bad LLVM IR.
76

7+
"""
8+
LineInfoNode(file::Symbol, line::Int32, [inlined_at::Int32])
9+
10+
Represents line information about a statement; Inlined statements has a non-zero
11+
`inlined_at` which represents the "parent" location in the linetable array.
12+
"""
13+
struct LineInfoNode
14+
file::Symbol
15+
line::Int32
16+
inlined_at::Int32
17+
end
18+
LineInfoNode(file, line) = LineInfoNode(file, line, Int32(0))
19+
820
struct Undefined end
921
const undef = Undefined()
1022

src/ir/wrap.jl

Lines changed: 72 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,26 @@ using MacroTools: isexpr, prewalk
44

55
using ..Inner, ..IRTools
66
import ..Inner: IR, Variable, Statement, Branch, BasicBlock, Meta, block!,
7-
unreachable, varmap, argument!, branch!, return!
7+
unreachable, varmap, argument!, branch!, return!, LineInfoNode
88
import Core: CodeInfo, GotoNode, SSAValue
99
import Core.Compiler: IRCode, CFG, GotoIfNot, ReturnNode, StmtRange
1010

1111
@static if VERSION > v"1.6-"
1212
import Core.Compiler: InstructionStream
1313
end
1414

15+
@static if VERSION v"1.9.0-DEV.502"
16+
const LineType = Int32
17+
else
18+
const LineType = Int
19+
end
20+
21+
@static if VERSION v"1.12.0-DEV.173"
22+
addline!(lines, li) = push!(lines, li, Int32(0), Int32(0))
23+
else
24+
addline!(lines, li) = push!(lines, li)
25+
end
26+
1527
unvars(ex) = prewalk(x -> x isa Variable ? SSAValue(x.id) : x, ex)
1628

1729
function IRCode(ir::IR)
@@ -34,7 +46,7 @@ function IRCode(ir::IR)
3446
end
3547
push!(stmts, ex)
3648
push!(types, st.type)
37-
push!(lines, st.line)
49+
addline!(lines, st.line)
3850
end
3951
for br in BasicBlock(b).branches
4052
if IRTools.isreturn(br)
@@ -52,7 +64,7 @@ function IRCode(ir::IR)
5264
cond = get(defs, br.condition, br.condition) |> unvars
5365
push!(stmts, GotoIfNot(cond, br.block))
5466
end
55-
push!(types, Any); push!(lines, 0)
67+
push!(types, Any); addline!(lines, Int32(0))
5668
end
5769
push!(index, length(stmts)+1)
5870
end
@@ -61,7 +73,8 @@ function IRCode(ir::IR)
6173
preds = map.(x -> x.id, IRTools.predecessors.(IRTools.blocks(ir)))
6274
bs = Core.Compiler.BasicBlock.(ranges, preds, succs)
6375
cfg = CFG(bs, index)
64-
flags = [0x00 for _ in stmts]
76+
77+
flags = UInt32[0x00 for _ in stmts]
6578
sps = VERSION > v"1.2-" ? (VERSION >= v"1.10.0-DEV.552" ? Core.Compiler.VarState[] : []) : Core.svec()
6679

6780
@static if VERSION > v"1.6-"
@@ -72,7 +85,39 @@ function IRCode(ir::IR)
7285
end
7386
stmts = InstructionStream(stmts, types, stmtinfo, lines, flags)
7487
meta = @static VERSION < v"1.9.0-DEV.472" ? [] : Expr[]
75-
IRCode(stmts, cfg, ir.lines, ir.blocks[1].argtypes, meta, sps)
88+
@static if VERSION v"1.12.0-DEV.173"
89+
nlocs = length(types)
90+
codelocs = fill(Int32(0), 3nlocs)
91+
92+
if !isempty(ir.lines)
93+
LI = first(ir.lines)
94+
topfile, topline = LI.file, LI.line
95+
96+
for i in 1:nlocs
97+
lineidx = lines[3i - 2]
98+
if lineidx == 0
99+
continue
100+
end
101+
# TODO: support inlining, see passes/inline.jl
102+
@assert LI.file === topfile && LI.inlined_at == 0
103+
LI = ir.lines[lineidx]
104+
codelocs[3i - 2] = LI.line
105+
end
106+
else
107+
topline = Int32(1)
108+
end
109+
codelocs = @ccall jl_compress_codelocs(topline::Int32, codelocs::Any, nlocs::Csize_t)::Any
110+
111+
debuginfo = Core.Compiler.DebugInfoStream(lines)
112+
debuginfo.def = ir.meta isa Meta ? ir.meta.instance : :var"n/a"
113+
debuginfo.linetable = Core.DebugInfo(debuginfo.def, nothing, Core.svec(), codelocs)
114+
IRCode(stmts, cfg, debuginfo, ir.blocks[1].argtypes, meta, sps)
115+
else
116+
mod, meth = ir.meta isa Meta ? (ir.meta.method.module, ir.meta.method) : (Main, nothing)
117+
linetable = map(li -> Core.LineInfoNode(mod, meth, li.file, LineType(li.line), LineType(li.inlined_at)),
118+
ir.lines)
119+
IRCode(stmts, cfg, linetable, ir.blocks[1].argtypes, meta, sps)
120+
end
76121
else
77122
IRCode(stmts, types, lines, flags, cfg, ir.lines, ir.blocks[1].argtypes, [], sps)
78123
end
@@ -118,7 +163,27 @@ slotname(ci, s) = Symbol(:_, s.id)
118163

119164
function IR(ci::CodeInfo, nargs::Integer; meta = nothing)
120165
bs = blockstarts(ci)
121-
ir = IR(Core.LineInfoNode[ci.linetable...], meta = meta)
166+
codelocs, linetable = @static if VERSION v"1.12.0-DEV.173"
167+
def = isnothing(meta) ? :var"n/a" : meta.instance
168+
N = length(ci.code)
169+
codelocs = fill(0, N)
170+
linetable = LineInfoNode[]
171+
172+
# NOTE: we could be faster about decoding here and support inlining?
173+
for pc in 1:N
174+
LI = Base.IRShow.buildLineInfoNode(ci.debuginfo, def, pc)
175+
if !isempty(LI)
176+
linode = first(LI) # ::Base.IRShow.LineInfoNode
177+
push!(linetable, LineInfoNode(linode.file, linode.line))
178+
codelocs[pc] = length(linetable)
179+
end
180+
end
181+
182+
codelocs, linetable
183+
else
184+
ci.codelocs, map(li -> LineInfoNode(li.file, li.line), ci.linetable)
185+
end
186+
ir = IR(linetable, meta = meta)
122187
_rename = Dict()
123188
rename(ex) = prewalk(ex) do x
124189
haskey(_rename, x) && return _rename[x]
@@ -151,7 +216,7 @@ function IR(ci::CodeInfo, nargs::Integer; meta = nothing)
151216
elseif isreturn(ex)
152217
return!(ir, rename(retval(ex)))
153218
else
154-
_rename[Core.SSAValue(i)] = push!(ir, IRTools.stmt(rename(ex), line = ci.codelocs[i]))
219+
_rename[Core.SSAValue(i)] = push!(ir, IRTools.stmt(rename(ex), line = codelocs[i]))
155220
end
156221
end
157222
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)