96
96
Get the `Core.Compiler.SlotNumber` associated with the `s::Symbol` in `ci::CodeInfo`. If there is no associated `Core.Compiler.SlotNumber`, returns `nothing`.
97
97
""" , get_slot)
98
98
99
- walk (fn, x) = fn (x)
100
- walk (fn, x:: Variable ) = fn (x)
101
- walk (fn, x:: Core.SlotNumber ) = fn (x)
102
- walk (fn, x:: Core.NewvarNode ) = Core. NewvarNode (walk (fn, x. slot))
103
- walk (fn, x:: Core.ReturnNode ) = Core. ReturnNode (walk (fn, x. val))
104
- walk (fn, x:: Core.GotoNode ) = Core. GotoNode (walk (fn, x. label))
105
- walk (fn, x:: Core.GotoIfNot ) = Core. GotoIfNot (walk (fn, x. cond), walk (fn, x. dest))
106
- walk (fn, x:: Expr ) = Expr (x. head, map (a -> walk (fn, a), x. args)... )
107
- function walk (fn, x:: Vector )
99
+ walk (fn, x, guard ) = fn (x)
100
+ walk (fn, x:: Variable , guard ) = fn (x)
101
+ walk (fn, x:: Core.SlotNumber , guard ) = fn (x)
102
+ walk (fn, x:: Core.NewvarNode , guard ) = Core. NewvarNode (walk (fn, x. slot, guard ))
103
+ walk (fn, x:: Core.ReturnNode , guard ) = Core. ReturnNode (walk (fn, x. val, guard ))
104
+ walk (fn, x:: Core.GotoNode , guard ) = Core. GotoNode (walk (fn, x. label, guard ))
105
+ walk (fn, x:: Core.GotoIfNot , guard ) = Core. GotoIfNot (walk (fn, x. cond, guard ), walk (fn, x. dest, guard ))
106
+ walk (fn, x:: Expr , guard ) = Expr (x. head, map (a -> walk (fn, a, guard ), x. args)... )
107
+ function walk (fn, x:: Vector , guard )
108
108
map (x) do el
109
- walk (fn, el)
109
+ walk (fn, el, guard )
110
110
end
111
111
end
112
+ walk (fn, x) = walk (fn, x, Val (:no_catch ))
112
113
113
114
@doc (
114
115
"""
@@ -130,7 +131,7 @@ struct Statement{T}
130
131
end
131
132
Statement (node:: T ) where T = Statement (node, Union{})
132
133
unwrap (stmt:: Statement ) = stmt. node
133
- walk (fn, stmt:: Statement{T} ) where T = Statement (walk (fn, stmt. node), stmt. type)
134
+ walk (fn, stmt:: Statement{T} , guard ) where T = Statement (walk (fn, stmt. node, guard ), stmt. type)
134
135
135
136
const stmt = Statement
136
137
@@ -245,17 +246,49 @@ setindex!(c::Canvas, x, v::Variable) = setindex!(c, x, v.id)
245
246
function delete! (c:: Canvas , idx:: Int )
246
247
c. code[idx] = nothing
247
248
c. defs[idx] = (idx, - 1 )
249
+ return nothing
248
250
end
249
251
delete! (c:: Canvas , v:: Variable ) = delete! (c, v. id)
250
252
251
253
_get (d:: Dict , c, k) = c
252
254
_get (d:: Dict , c:: Variable , k) = haskey (d, c. id) ? Variable (getindex (d, c. id)) : nothing
255
+ function _get (d:: Dict , c:: Core.GotoIfNot , k)
256
+ v = c. dest
257
+ if haskey (d, v)
258
+ nv = getindex (d, v)
259
+ else
260
+ nv = findfirst (l -> l > v, d)
261
+ if nv === nothing
262
+ nv = maximum (d)[1 ]
263
+ end
264
+ nv = getindex (d, nv)
265
+ end
266
+ c = _get (d, c. cond, c. cond)
267
+ return Core. GotoIfNot (c, nv)
268
+ end
269
+ function _get (d:: Dict , c:: Core.GotoNode , k)
270
+ v = c. label
271
+ if haskey (d, v)
272
+ nv = getindex (d, v)
273
+ else
274
+ nv = findfirst (l -> l > v, d)
275
+ if nv === nothing
276
+ nv = maximum (d)[1 ]
277
+ end
278
+ nv = getindex (d, nv)
279
+ end
280
+ return Core. GotoNode (nv)
281
+ end
282
+
283
+ # Override for renumber.
284
+ walk (fn, c:: Core.GotoIfNot , :: Val{:catch_jumps} ) = fn (c)
285
+ walk (fn, c:: Core.GotoNode , :: Val{:catch_jumps} ) = fn (c)
253
286
254
287
function renumber (c:: Canvas )
255
288
s = sort (filter (v -> v[2 ] > 0 , c. defs); by = x -> x[2 ])
256
289
d = Dict ((s[i][1 ], i) for i in 1 : length (s))
257
290
ind = first .(s)
258
- swap = walk (k -> _get (d, k, k), c. code)
291
+ swap = walk (k -> _get (d, k, k), c. code, Val ( :catch_jumps ) )
259
292
return Canvas (Tuple{Int, Int}[(i, i) for i in 1 : length (s)],
260
293
getindex (swap, ind), getindex (c. codelocs, ind))
261
294
end
424
457
425
458
function Base. delete! (b:: Builder , v:: Union{Variable, NewVariable} )
426
459
v′ = substitute (b, v)
427
- delete! (b. to, v′)
460
+ substitute! (b, v′, delete! (b. to, v′) )
428
461
end
429
462
430
463
function slot! (b:: Builder , name:: Symbol ; arg = false )
@@ -445,6 +478,7 @@ Add a new `Core.SlotNumber` with associated `name::Symbol` to the in-progress `C
445
478
`name::Symbol` must not already be associated with a `Core.SlotNumber`.
446
479
""" , slot!)
447
480
481
+ return! (b:: Builder , v) = push! (b, Core. ReturnNode (v))
448
482
return! (b:: Builder , v:: Variable ) = push! (b, Core. ReturnNode (v))
449
483
return! (b:: Builder , v:: NewVariable ) = push! (b, Core. ReturnNode (v))
450
484
0 commit comments