-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
/
Copy pathlegacy.jl
97 lines (92 loc) · 4.02 KB
/
legacy.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# This file is a part of Julia. License is MIT: https://julialang.org/license
"""
inflate_ir!(ci::CodeInfo, linfo::MethodInstance) -> ir::IRCode
inflate_ir!(ci::CodeInfo, sptypes::Vector{VarState}, argtypes::Vector{Any}) -> ir::IRCode
Inflates `ci::CodeInfo`-IR to `ir::IRCode`-format.
This should be used with caution as it is a in-place transformation where the fields of
the original `ci::CodeInfo` are modified.
"""
function inflate_ir!(ci::CodeInfo, linfo::MethodInstance)
sptypes = sptypes_from_meth_instance(linfo)
argtypes, _ = matching_cache_argtypes(fallback_lattice, linfo)
return inflate_ir!(ci, sptypes, argtypes)
end
function inflate_ir!(ci::CodeInfo, sptypes::Vector{VarState}, argtypes::Vector{Any})
code = ci.code
cfg = compute_basic_blocks(code)
for i = 1:length(code)
stmt = code[i]
# Translate statement edges to bb_edges
if isa(stmt, GotoNode)
code[i] = GotoNode(block_for_inst(cfg, stmt.label))
elseif isa(stmt, GotoIfNot)
code[i] = GotoIfNot(stmt.cond, block_for_inst(cfg, stmt.dest))
elseif isa(stmt, PhiNode)
code[i] = PhiNode(Int32[block_for_inst(cfg, Int(edge)) for edge in stmt.edges], stmt.values)
elseif isa(stmt, EnterNode)
code[i] = EnterNode(stmt, stmt.catch_dest == 0 ? 0 : block_for_inst(cfg, stmt.catch_dest))
end
end
nstmts = length(code)
ssavaluetypes = ci.ssavaluetypes
if !isa(ssavaluetypes, Vector{Any})
ssavaluetypes = Any[ Any for i = 1:ssavaluetypes::Int ]
end
info = CallInfo[NoCallInfo() for i = 1:nstmts]
stmts = InstructionStream(code, ssavaluetypes, info, ci.codelocs, ci.ssaflags)
linetable = ci.linetable
if !isa(linetable, Vector{LineInfoNode})
linetable = collect(LineInfoNode, linetable::Vector{Any})::Vector{LineInfoNode}
end
meta = Expr[]
return IRCode(stmts, cfg, linetable, argtypes, meta, sptypes)
end
"""
inflate_ir(ci::CodeInfo, linfo::MethodInstance) -> ir::IRCode
inflate_ir(ci::CodeInfo, sptypes::Vector{VarState}, argtypes::Vector{Any}) -> ir::IRCode
inflate_ir(ci::CodeInfo) -> ir::IRCode
Non-destructive version of `inflate_ir!`.
Mainly used for testing or interactive use.
"""
inflate_ir(ci::CodeInfo, linfo::MethodInstance) = inflate_ir!(copy(ci), linfo)
inflate_ir(ci::CodeInfo, sptypes::Vector{VarState}, argtypes::Vector{Any}) = inflate_ir!(copy(ci), sptypes, argtypes)
function inflate_ir(ci::CodeInfo)
# XXX the length of `ci.slotflags` may be different from the actual number of call
# arguments, but we really don't know that information in this case
argtypes = Any[ Any for i = 1:length(ci.slotflags) ]
return inflate_ir(ci, VarState[], argtypes)
end
function replace_code_newstyle!(ci::CodeInfo, ir::IRCode)
@assert isempty(ir.new_nodes)
# All but the first `nargs` slots will now be unused
nargs = length(ir.argtypes)
resize!(ci.slotnames, nargs)
resize!(ci.slotflags, nargs)
resize!(ci.slottypes, nargs)
stmts = ir.stmts
code = ci.code = stmts.stmt
ssavaluetypes = ci.ssavaluetypes = stmts.type
codelocs = ci.codelocs = stmts.line
ssaflags = ci.ssaflags = stmts.flag
linetable = ci.linetable = ir.linetable
for metanode in ir.meta
push!(code, metanode)
push!(codelocs, 1)
push!(ssavaluetypes, Any)
push!(ssaflags, IR_FLAG_NULL)
end
# Translate BB Edges to statement edges
# (and undo normalization for now)
for i = 1:length(code)
stmt = code[i]
if isa(stmt, GotoNode)
code[i] = GotoNode(first(ir.cfg.blocks[stmt.label].stmts))
elseif isa(stmt, GotoIfNot)
code[i] = GotoIfNot(stmt.cond, first(ir.cfg.blocks[stmt.dest].stmts))
elseif isa(stmt, PhiNode)
code[i] = PhiNode(Int32[edge == 0 ? 0 : last(ir.cfg.blocks[edge].stmts) for edge in stmt.edges], stmt.values)
elseif isa(stmt, EnterNode)
code[i] = EnterNode(stmt, stmt.catch_dest == 0 ? 0 : first(ir.cfg.blocks[stmt.catch_dest].stmts))
end
end
end