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 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
# This file is a part of Julia. License is MIT: https://julialang.org/license
using Core: LineInfoNode
const NullLineInfo = LineInfoNode(@__MODULE__, Symbol(""), Symbol(""), 0, 0)
if false
import Base: Base, @show
else
macro show(s)
return :(println(stdout, $(QuoteNode(s)), " = ", $(esc(s))))
end
end
include("compiler/ssair/ir.jl")
include("compiler/ssair/domtree.jl")
include("compiler/ssair/slot2ssa.jl")
include("compiler/ssair/queries.jl")
include("compiler/ssair/passes.jl")
include("compiler/ssair/inlining.jl")
include("compiler/ssair/verify.jl")
include("compiler/ssair/legacy.jl")
#@isdefined(Base) && include("compiler/ssair/show.jl")
function normalize_expr(stmt::Expr)
if stmt.head === :gotoifnot
return GotoIfNot(stmt.args[1], stmt.args[2]::Int)
elseif stmt.head === :return
return (length(stmt.args) == 0) ? ReturnNode(nothing) : ReturnNode(stmt.args[1])
elseif stmt.head === :unreachable
return ReturnNode()
else
return stmt
end
end
function normalize(@nospecialize(stmt), meta::Vector{Any})
if isa(stmt, Expr)
if stmt.head == :meta
args = stmt.args
if length(args) > 0
push!(meta, stmt)
end
return nothing
elseif stmt.head === :line
return nothing # deprecated - we shouldn't encounter this
else
return normalize_expr(stmt)
end
end
return stmt
end
function just_construct_ssa(ci::CodeInfo, code::Vector{Any}, nargs::Int, sv::OptimizationState)
# Go through and add an unreachable node after every
# Union{} call. Then reindex labels.
idx = 1
oldidx = 1
changemap = fill(0, length(code))
while idx <= length(code)
if code[idx] isa Expr && ci.ssavaluetypes[idx] === Union{}
if !(idx < length(code) && isexpr(code[idx+1], :unreachable))
insert!(code, idx + 1, ReturnNode())
insert!(ci.codelocs, idx + 1, ci.codelocs[idx])
insert!(ci.ssavaluetypes, idx + 1, Union{})
if oldidx < length(changemap)
changemap[oldidx + 1] = 1
end
idx += 1
end
end
idx += 1
oldidx += 1
end
renumber_ir_elements!(code, changemap)
inbounds_depth = 0 # Number of stacked inbounds
meta = Any[]
flags = fill(0x00, length(code))
for i = 1:length(code)
stmt = code[i]
if isexpr(stmt, :inbounds)
arg1 = stmt.args[1]
if arg1 === true # push
inbounds_depth += 1
elseif arg1 === false # clear
inbounds_depth = 0
elseif inbounds_depth > 0 # pop
inbounds_depth -= 1
end
stmt = nothing
else
stmt = normalize(stmt, meta)
end
code[i] = stmt
if !(stmt === nothing)
if inbounds_depth > 0
flags[i] |= IR_FLAG_INBOUNDS
end
end
end
strip_trailing_junk!(ci, code, flags)
cfg = compute_basic_blocks(code)
defuse_insts = scan_slot_def_use(nargs, ci, code)
@timeit "domtree 1" domtree = construct_domtree(cfg)
ir = let code = Any[nothing for _ = 1:length(code)]
argtypes = sv.slottypes[1:(nargs+1)]
IRCode(code, Any[], ci.codelocs, flags, cfg, collect(LineInfoNode, ci.linetable), argtypes, meta, sv.sp)
end
@timeit "construct_ssa" ir = construct_ssa!(ci, code, ir, domtree, defuse_insts, nargs, sv.sp, sv.slottypes)
return ir
end
function run_passes(ci::CodeInfo, nargs::Int, sv::OptimizationState)
ir = just_construct_ssa(ci, copy_exprargs(ci.code), nargs, sv)
#@Base.show ("after_construct", ir)
# TODO: Domsorting can produce an updated domtree - no need to recompute here
@timeit "compact 1" ir = compact!(ir)
@timeit "Inlining" ir = ssa_inlining_pass!(ir, ir.linetable, sv)
#@timeit "verify 2" verify_ir(ir)
@timeit "domtree 2" domtree = construct_domtree(ir.cfg)
ir = compact!(ir)
#@Base.show ("before_sroa", ir)
@timeit "SROA" ir = getfield_elim_pass!(ir, domtree)
#@Base.show ir.new_nodes
#@Base.show ("after_sroa", ir)
ir = adce_pass!(ir)
#@Base.show ("after_adce", ir)
@timeit "type lift" ir = type_lift_pass!(ir)
@timeit "compact 3" ir = compact!(ir)
#@Base.show ir
if JLOptions().debug_level == 2
@timeit "verify 3" (verify_ir(ir); verify_linetable(ir.linetable))
end
return ir
end
|