Skip to content

Commit

Permalink
optimizer: add Instruction/InstructionStream abstraction (JuliaLang#3…
Browse files Browse the repository at this point in the history
  • Loading branch information
vtjnash authored Jun 16, 2020
1 parent c54a6ea commit 0a2644a
Show file tree
Hide file tree
Showing 14 changed files with 580 additions and 484 deletions.
4 changes: 2 additions & 2 deletions base/compiler/compiler.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ using Core.Intrinsics, Core.IR
import Core: print, println, show, write, unsafe_write, stdout, stderr,
_apply, _apply_iterate, svec, apply_type, Builtin, IntrinsicFunction, MethodInstance, CodeInstance

const getproperty = getfield
const setproperty! = setfield!
const getproperty = Core.getfield
const setproperty! = Core.setfield!

ccall(:jl_set_istopmod, Cvoid, (Any, Bool), Compiler, false)

Expand Down
5 changes: 3 additions & 2 deletions base/compiler/optimize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,9 @@ function optimize(opt::OptimizationState, params::OptimizationParams, @nospecial
if length(ir.stmts) < 10
proven_pure = true
for i in 1:length(ir.stmts)
stmt = ir.stmts[i]
if stmt_affects_purity(stmt, ir) && !stmt_effect_free(stmt, ir.types[i], ir, ir.sptypes)
node = ir.stmts[i]
stmt = node[:inst]
if stmt_affects_purity(stmt, ir) && !stmt_effect_free(stmt, node[:type], ir, ir.sptypes)
proven_pure = false
break
end
Expand Down
6 changes: 4 additions & 2 deletions base/compiler/ssair/driver.jl
Original file line number Diff line number Diff line change
Expand Up @@ -116,14 +116,16 @@ function convert_to_ircode(ci::CodeInfo, code::Vector{Any}, coverage::Bool, narg
end
strip_trailing_junk!(ci, code, flags)
cfg = compute_basic_blocks(code)
ir = IRCode(code, Any[], ci.codelocs, flags, cfg, collect(LineInfoNode, ci.linetable), sv.slottypes, meta, sv.sptypes)
types = Any[]
stmts = InstructionStream(code, types, ci.codelocs, flags)
ir = IRCode(stmts, cfg, collect(LineInfoNode, ci.linetable), sv.slottypes, meta, sv.sptypes)
return ir
end

function slot2reg(ir::IRCode, ci::CodeInfo, nargs::Int, sv::OptimizationState)
# need `ci` for the slot metadata, IR for the code
@timeit "domtree 1" domtree = construct_domtree(ir.cfg)
defuse_insts = scan_slot_def_use(nargs, ci, ir.stmts)
defuse_insts = scan_slot_def_use(nargs, ci, ir.stmts.inst)
@timeit "construct_ssa" ir = construct_ssa!(ci, ir, domtree, defuse_insts, nargs, sv.sptypes, sv.slottypes) # consumes `ir`
return ir
end
Expand Down
58 changes: 29 additions & 29 deletions base/compiler/ssair/inlining.jl
Original file line number Diff line number Diff line change
Expand Up @@ -303,19 +303,19 @@ function ir_inline_item!(compact::IncrementalCompact, idx::Int, argexprs::Vector
boundscheck::Symbol, todo_bbs::Vector{Tuple{Int, Int}})
# Ok, do the inlining here
inline_cfg = item.ir.cfg
stmt = compact.result[idx]
linetable_offset = length(linetable)
stmt = compact.result[idx][:inst]
linetable_offset::Int32 = length(linetable)
# Append the linetable of the inlined function to our line table
inlined_at = Int(compact.result_lines[idx])
inlined_at = Int(compact.result[idx][:line])
for entry in item.linetable
push!(linetable, LineInfoNode(entry.method, entry.file, entry.line,
(entry.inlined_at > 0 ? entry.inlined_at + linetable_offset : inlined_at)))
end
if item.isva
vararg = mk_tuplecall!(compact, argexprs[item.na:end], compact.result_lines[idx])
vararg = mk_tuplecall!(compact, argexprs[item.na:end], compact.result[idx][:line])
argexprs = Any[argexprs[1:(item.na - 1)]..., vararg]
end
flag = compact.result_flags[idx]
flag = compact.result[idx][:flag]
boundscheck_idx = boundscheck
if boundscheck_idx === :default || boundscheck_idx === :propagate
if (flag & IR_FLAG_INBOUNDS) != 0
Expand All @@ -341,7 +341,7 @@ function ir_inline_item!(compact::IncrementalCompact, idx::Int, argexprs::Vector
return_value = SSAValue(idx′)
inline_compact[idx′] = stmt′.val
val = stmt′.val
inline_compact.result_types[idx′] = (isa(val, Argument) || isa(val, Expr)) ?
inline_compact.result[idx′][:type] = (isa(val, Argument) || isa(val, Expr)) ?
compact_exprtype(compact, stmt′.val) :
compact_exprtype(inline_compact, stmt′.val)
break
Expand Down Expand Up @@ -371,11 +371,11 @@ function ir_inline_item!(compact::IncrementalCompact, idx::Int, argexprs::Vector
push!(pn.edges, inline_compact.active_result_bb-1)
if isa(val, GlobalRef) || isa(val, Expr)
stmt′ = val
inline_compact.result_types[idx′] = (isa(val, Argument) || isa(val, Expr)) ?
inline_compact.result[idx′][:type] = (isa(val, Argument) || isa(val, Expr)) ?
compact_exprtype(compact, val) :
compact_exprtype(inline_compact, val)
insert_node_here!(inline_compact, GotoNode(post_bb_id),
Any, compact.result_lines[idx′],
Any, compact.result[idx′][:line],
true)
push!(pn.values, SSAValue(idx′))
else
Expand Down Expand Up @@ -407,7 +407,7 @@ function ir_inline_item!(compact::IncrementalCompact, idx::Int, argexprs::Vector
if length(pn.edges) == 1
return_value = pn.values[1]
else
return_value = insert_node_here!(compact, pn, compact_exprtype(compact, SSAValue(idx)), compact.result_lines[idx])
return_value = insert_node_here!(compact, pn, compact_exprtype(compact, SSAValue(idx)), compact.result[idx][:line])
end
end
return_value
Expand All @@ -418,7 +418,7 @@ const fatal_type_bound_error = ErrorException("fatal error in type inference (ty
function ir_inline_unionsplit!(compact::IncrementalCompact, idx::Int,
argexprs::Vector{Any}, linetable::Vector{LineInfoNode},
item::UnionSplit, boundscheck::Symbol, todo_bbs::Vector{Tuple{Int, Int}})
stmt, typ, line = compact.result[idx], compact.result_types[idx], compact.result_lines[idx]
stmt, typ, line = compact.result[idx][:inst], compact.result[idx][:type], compact.result[idx][:line]
atype = item.atype
generic_bb = item.bbs[end-1]
join_bb = item.bbs[end]
Expand Down Expand Up @@ -541,12 +541,13 @@ function batch_inline!(todo::Vector{Any}, ir::IRCode, linetable::Vector{LineInfo
for aidx in 1:length(argexprs)
aexpr = argexprs[aidx]
if isa(aexpr, GlobalRef) || isa(aexpr, Expr)
argexprs[aidx] = insert_node_here!(compact, aexpr, compact_exprtype(compact, aexpr), compact.result_lines[idx])
argexprs[aidx] = insert_node_here!(compact, aexpr, compact_exprtype(compact, aexpr), compact.result[idx][:line])
end
end
if isinvoke(item)
argexprs = rewrite_invoke_exprargs!((node, typ)->insert_node_here!(compact, node, typ, compact.result_lines[idx]),
argexprs)
argexprs = rewrite_invoke_exprargs!(argexprs) do node, typ
insert_node_here!(compact, node, typ, compact.result[idx][:line])
end
end
if isa(item, InliningTodo)
compact.ssa_rename[compact.idx-1] = ir_inline_item!(compact, idx, argexprs, linetable, item, boundscheck, state.todo_bbs)
Expand Down Expand Up @@ -841,8 +842,8 @@ function is_valid_type_for_apply_rewrite(@nospecialize(typ), params::Optimizatio
end

function inline_splatnew!(ir::IRCode, idx::Int)
stmt = ir.stmts[idx]
ty = ir.types[idx]
stmt = ir.stmts[idx][:inst]
ty = ir.stmts[idx][:type]
nf = nfields_tfunc(ty)
if nf isa Const
eargs = stmt.args
Expand Down Expand Up @@ -874,7 +875,6 @@ function call_sig(ir::IRCode, stmt::Expr)
f = singleton_type(ft)
f === Core.Intrinsics.llvmcall && return nothing
f === Core.Intrinsics.cglobal && return nothing

atypes = Vector{Any}(undef, length(stmt.args))
atypes[1] = ft
ok = true
Expand All @@ -888,7 +888,7 @@ function call_sig(ir::IRCode, stmt::Expr)
end

function inline_apply!(ir::IRCode, idx::Int, sig::Signature, params::OptimizationParams)
stmt = ir.stmts[idx]
stmt = ir.stmts[idx][:inst]
while sig.f === Core._apply || sig.f === Core._apply_iterate
arg_start = sig.f === Core._apply ? 2 : 3
atypes = sig.atypes
Expand All @@ -911,7 +911,7 @@ function inline_apply!(ir::IRCode, idx::Int, sig::Signature, params::Optimizatio
break
end
if nonempty_idx != 0
ir.stmts[idx] = stmt.args[nonempty_idx]
ir.stmts[idx][:inst] = stmt.args[nonempty_idx]
return nothing
end
end
Expand Down Expand Up @@ -941,8 +941,8 @@ is_builtin(s::Signature) =
s.ft Builtin

function inline_invoke!(ir::IRCode, idx::Int, sig::Signature, invoke_data::InvokeData, sv::OptimizationState, todo::Vector{Any})
stmt = ir.stmts[idx]
calltype = ir.types[idx]
stmt = ir.stmts[idx][:inst]
calltype = ir.stmts[idx][:type]
method = invoke_data.entry.func
(metharg, methsp) = ccall(:jl_type_intersection_with_env, Any, (Any, Any),
sig.atype, method.sig)::SimpleVector
Expand All @@ -958,7 +958,7 @@ end
# this method does not access the method table or otherwise process generic
# functions.
function process_simple!(ir::IRCode, idx::Int, params::OptimizationParams, world::UInt)
stmt = ir.stmts[idx]
stmt = ir.stmts[idx][:inst]
stmt isa Expr || return nothing
if stmt.head === :splatnew
inline_splatnew!(ir, idx)
Expand All @@ -975,10 +975,10 @@ function process_simple!(ir::IRCode, idx::Int, params::OptimizationParams, world
sig === nothing && return nothing

# Check if we match any of the early inliners
calltype = ir.types[idx]
calltype = ir.stmts[idx][:type]
res = early_inline_special_case(ir, sig, stmt, params, calltype)
if res !== nothing
ir.stmts[idx] = res
ir.stmts[idx][:inst] = res
return nothing
end

Expand Down Expand Up @@ -1013,8 +1013,8 @@ function assemble_inline_todo!(ir::IRCode, sv::OptimizationState)
r = process_simple!(ir, idx, sv.params, sv.world)
r === nothing && continue

stmt = ir.stmts[idx]
calltype = ir.types[idx]
stmt = ir.stmts[idx][:inst]
calltype = ir.stmts[idx][:type]
(sig, invoke_data) = r

# Ok, now figure out what method to call
Expand Down Expand Up @@ -1213,8 +1213,8 @@ function early_inline_special_case(ir::IRCode, s::Signature, e::Expr, params::Op
end

function late_inline_special_case!(ir::IRCode, sig::Signature, idx::Int, stmt::Expr, params::OptimizationParams)
typ = ir.types[idx]
f, ft, atypes = sig.f, sig.ft, sig.atypes
typ = ir.stmts[idx][:type]
if params.inlining && length(atypes) == 3 && istopfunction(f, :!==)
# special-case inliner for !== that precedes _methods_by_ftype union splitting
# and that works, even though inference generally avoids inferring the `!==` Method
Expand Down Expand Up @@ -1251,9 +1251,9 @@ end

function ssa_substitute!(idx::Int, @nospecialize(val), arg_replacements::Vector{Any},
@nospecialize(spsig), spvals::Vector{Any},
linetable_offset::Int, boundscheck::Symbol, compact::IncrementalCompact)
compact.result_flags[idx] &= ~IR_FLAG_INBOUNDS
compact.result_lines[idx] += linetable_offset
linetable_offset::Int32, boundscheck::Symbol, compact::IncrementalCompact)
compact.result[idx][:flag] &= ~IR_FLAG_INBOUNDS
compact.result[idx][:line] += linetable_offset
return ssa_substitute_op!(val, arg_replacements, spsig, spvals, boundscheck)
end

Expand Down
Loading

0 comments on commit 0a2644a

Please sign in to comment.