@@ -4,14 +4,26 @@ using MacroTools: isexpr, prewalk
4
4
5
5
using .. Inner, .. IRTools
6
6
import .. Inner: IR, Variable, Statement, Branch, BasicBlock, Meta, block!,
7
- unreachable, varmap, argument!, branch!, return !
7
+ unreachable, varmap, argument!, branch!, return !, LineInfoNode
8
8
import Core: CodeInfo, GotoNode, SSAValue
9
9
import Core. Compiler: IRCode, CFG, GotoIfNot, ReturnNode, StmtRange
10
10
11
11
@static if VERSION > v " 1.6-"
12
12
import Core. Compiler: InstructionStream
13
13
end
14
14
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
+
15
27
unvars (ex) = prewalk (x -> x isa Variable ? SSAValue (x. id) : x, ex)
16
28
17
29
function IRCode (ir:: IR )
@@ -34,7 +46,7 @@ function IRCode(ir::IR)
34
46
end
35
47
push! (stmts, ex)
36
48
push! (types, st. type)
37
- push ! (lines, st. line)
49
+ addline ! (lines, st. line)
38
50
end
39
51
for br in BasicBlock (b). branches
40
52
if IRTools. isreturn (br)
@@ -52,7 +64,7 @@ function IRCode(ir::IR)
52
64
cond = get (defs, br. condition, br. condition) |> unvars
53
65
push! (stmts, GotoIfNot (cond, br. block))
54
66
end
55
- push! (types, Any); push ! (lines, 0 )
67
+ push! (types, Any); addline ! (lines, Int32 ( 0 ) )
56
68
end
57
69
push! (index, length (stmts)+ 1 )
58
70
end
@@ -61,7 +73,8 @@ function IRCode(ir::IR)
61
73
preds = map .(x -> x. id, IRTools. predecessors .(IRTools. blocks (ir)))
62
74
bs = Core. Compiler. BasicBlock .(ranges, preds, succs)
63
75
cfg = CFG (bs, index)
64
- flags = [0x00 for _ in stmts]
76
+
77
+ flags = UInt32[0x00 for _ in stmts]
65
78
sps = VERSION > v " 1.2-" ? (VERSION >= v " 1.10.0-DEV.552" ? Core. Compiler. VarState[] : []) : Core. svec ()
66
79
67
80
@static if VERSION > v " 1.6-"
@@ -72,7 +85,39 @@ function IRCode(ir::IR)
72
85
end
73
86
stmts = InstructionStream (stmts, types, stmtinfo, lines, flags)
74
87
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 ), 3 nlocs)
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[3 i - 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[3 i - 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
76
121
else
77
122
IRCode (stmts, types, lines, flags, cfg, ir. lines, ir. blocks[1 ]. argtypes, [], sps)
78
123
end
@@ -118,7 +163,27 @@ slotname(ci, s) = Symbol(:_, s.id)
118
163
119
164
function IR (ci:: CodeInfo , nargs:: Integer ; meta = nothing )
120
165
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)
122
187
_rename = Dict ()
123
188
rename (ex) = prewalk (ex) do x
124
189
haskey (_rename, x) && return _rename[x]
@@ -151,7 +216,7 @@ function IR(ci::CodeInfo, nargs::Integer; meta = nothing)
151
216
elseif isreturn (ex)
152
217
return! (ir, rename (retval (ex)))
153
218
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]))
155
220
end
156
221
end
157
222
return ir
0 commit comments