Skip to content

Commit 0a2644a

Browse files
authored
optimizer: add Instruction/InstructionStream abstraction (#34306)
1 parent c54a6ea commit 0a2644a

File tree

14 files changed

+580
-484
lines changed

14 files changed

+580
-484
lines changed

base/compiler/compiler.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ using Core.Intrinsics, Core.IR
77
import Core: print, println, show, write, unsafe_write, stdout, stderr,
88
_apply, _apply_iterate, svec, apply_type, Builtin, IntrinsicFunction, MethodInstance, CodeInstance
99

10-
const getproperty = getfield
11-
const setproperty! = setfield!
10+
const getproperty = Core.getfield
11+
const setproperty! = Core.setfield!
1212

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

base/compiler/optimize.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,9 @@ function optimize(opt::OptimizationState, params::OptimizationParams, @nospecial
186186
if length(ir.stmts) < 10
187187
proven_pure = true
188188
for i in 1:length(ir.stmts)
189-
stmt = ir.stmts[i]
190-
if stmt_affects_purity(stmt, ir) && !stmt_effect_free(stmt, ir.types[i], ir, ir.sptypes)
189+
node = ir.stmts[i]
190+
stmt = node[:inst]
191+
if stmt_affects_purity(stmt, ir) && !stmt_effect_free(stmt, node[:type], ir, ir.sptypes)
191192
proven_pure = false
192193
break
193194
end

base/compiler/ssair/driver.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,16 @@ function convert_to_ircode(ci::CodeInfo, code::Vector{Any}, coverage::Bool, narg
116116
end
117117
strip_trailing_junk!(ci, code, flags)
118118
cfg = compute_basic_blocks(code)
119-
ir = IRCode(code, Any[], ci.codelocs, flags, cfg, collect(LineInfoNode, ci.linetable), sv.slottypes, meta, sv.sptypes)
119+
types = Any[]
120+
stmts = InstructionStream(code, types, ci.codelocs, flags)
121+
ir = IRCode(stmts, cfg, collect(LineInfoNode, ci.linetable), sv.slottypes, meta, sv.sptypes)
120122
return ir
121123
end
122124

123125
function slot2reg(ir::IRCode, ci::CodeInfo, nargs::Int, sv::OptimizationState)
124126
# need `ci` for the slot metadata, IR for the code
125127
@timeit "domtree 1" domtree = construct_domtree(ir.cfg)
126-
defuse_insts = scan_slot_def_use(nargs, ci, ir.stmts)
128+
defuse_insts = scan_slot_def_use(nargs, ci, ir.stmts.inst)
127129
@timeit "construct_ssa" ir = construct_ssa!(ci, ir, domtree, defuse_insts, nargs, sv.sptypes, sv.slottypes) # consumes `ir`
128130
return ir
129131
end

base/compiler/ssair/inlining.jl

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -303,19 +303,19 @@ function ir_inline_item!(compact::IncrementalCompact, idx::Int, argexprs::Vector
303303
boundscheck::Symbol, todo_bbs::Vector{Tuple{Int, Int}})
304304
# Ok, do the inlining here
305305
inline_cfg = item.ir.cfg
306-
stmt = compact.result[idx]
307-
linetable_offset = length(linetable)
306+
stmt = compact.result[idx][:inst]
307+
linetable_offset::Int32 = length(linetable)
308308
# Append the linetable of the inlined function to our line table
309-
inlined_at = Int(compact.result_lines[idx])
309+
inlined_at = Int(compact.result[idx][:line])
310310
for entry in item.linetable
311311
push!(linetable, LineInfoNode(entry.method, entry.file, entry.line,
312312
(entry.inlined_at > 0 ? entry.inlined_at + linetable_offset : inlined_at)))
313313
end
314314
if item.isva
315-
vararg = mk_tuplecall!(compact, argexprs[item.na:end], compact.result_lines[idx])
315+
vararg = mk_tuplecall!(compact, argexprs[item.na:end], compact.result[idx][:line])
316316
argexprs = Any[argexprs[1:(item.na - 1)]..., vararg]
317317
end
318-
flag = compact.result_flags[idx]
318+
flag = compact.result[idx][:flag]
319319
boundscheck_idx = boundscheck
320320
if boundscheck_idx === :default || boundscheck_idx === :propagate
321321
if (flag & IR_FLAG_INBOUNDS) != 0
@@ -341,7 +341,7 @@ function ir_inline_item!(compact::IncrementalCompact, idx::Int, argexprs::Vector
341341
return_value = SSAValue(idx′)
342342
inline_compact[idx′] = stmt′.val
343343
val = stmt′.val
344-
inline_compact.result_types[idx′] = (isa(val, Argument) || isa(val, Expr)) ?
344+
inline_compact.result[idx′][:type] = (isa(val, Argument) || isa(val, Expr)) ?
345345
compact_exprtype(compact, stmt′.val) :
346346
compact_exprtype(inline_compact, stmt′.val)
347347
break
@@ -371,11 +371,11 @@ function ir_inline_item!(compact::IncrementalCompact, idx::Int, argexprs::Vector
371371
push!(pn.edges, inline_compact.active_result_bb-1)
372372
if isa(val, GlobalRef) || isa(val, Expr)
373373
stmt′ = val
374-
inline_compact.result_types[idx′] = (isa(val, Argument) || isa(val, Expr)) ?
374+
inline_compact.result[idx′][:type] = (isa(val, Argument) || isa(val, Expr)) ?
375375
compact_exprtype(compact, val) :
376376
compact_exprtype(inline_compact, val)
377377
insert_node_here!(inline_compact, GotoNode(post_bb_id),
378-
Any, compact.result_lines[idx′],
378+
Any, compact.result[idx′][:line],
379379
true)
380380
push!(pn.values, SSAValue(idx′))
381381
else
@@ -407,7 +407,7 @@ function ir_inline_item!(compact::IncrementalCompact, idx::Int, argexprs::Vector
407407
if length(pn.edges) == 1
408408
return_value = pn.values[1]
409409
else
410-
return_value = insert_node_here!(compact, pn, compact_exprtype(compact, SSAValue(idx)), compact.result_lines[idx])
410+
return_value = insert_node_here!(compact, pn, compact_exprtype(compact, SSAValue(idx)), compact.result[idx][:line])
411411
end
412412
end
413413
return_value
@@ -418,7 +418,7 @@ const fatal_type_bound_error = ErrorException("fatal error in type inference (ty
418418
function ir_inline_unionsplit!(compact::IncrementalCompact, idx::Int,
419419
argexprs::Vector{Any}, linetable::Vector{LineInfoNode},
420420
item::UnionSplit, boundscheck::Symbol, todo_bbs::Vector{Tuple{Int, Int}})
421-
stmt, typ, line = compact.result[idx], compact.result_types[idx], compact.result_lines[idx]
421+
stmt, typ, line = compact.result[idx][:inst], compact.result[idx][:type], compact.result[idx][:line]
422422
atype = item.atype
423423
generic_bb = item.bbs[end-1]
424424
join_bb = item.bbs[end]
@@ -541,12 +541,13 @@ function batch_inline!(todo::Vector{Any}, ir::IRCode, linetable::Vector{LineInfo
541541
for aidx in 1:length(argexprs)
542542
aexpr = argexprs[aidx]
543543
if isa(aexpr, GlobalRef) || isa(aexpr, Expr)
544-
argexprs[aidx] = insert_node_here!(compact, aexpr, compact_exprtype(compact, aexpr), compact.result_lines[idx])
544+
argexprs[aidx] = insert_node_here!(compact, aexpr, compact_exprtype(compact, aexpr), compact.result[idx][:line])
545545
end
546546
end
547547
if isinvoke(item)
548-
argexprs = rewrite_invoke_exprargs!((node, typ)->insert_node_here!(compact, node, typ, compact.result_lines[idx]),
549-
argexprs)
548+
argexprs = rewrite_invoke_exprargs!(argexprs) do node, typ
549+
insert_node_here!(compact, node, typ, compact.result[idx][:line])
550+
end
550551
end
551552
if isa(item, InliningTodo)
552553
compact.ssa_rename[compact.idx-1] = ir_inline_item!(compact, idx, argexprs, linetable, item, boundscheck, state.todo_bbs)
@@ -841,8 +842,8 @@ function is_valid_type_for_apply_rewrite(@nospecialize(typ), params::Optimizatio
841842
end
842843

843844
function inline_splatnew!(ir::IRCode, idx::Int)
844-
stmt = ir.stmts[idx]
845-
ty = ir.types[idx]
845+
stmt = ir.stmts[idx][:inst]
846+
ty = ir.stmts[idx][:type]
846847
nf = nfields_tfunc(ty)
847848
if nf isa Const
848849
eargs = stmt.args
@@ -874,7 +875,6 @@ function call_sig(ir::IRCode, stmt::Expr)
874875
f = singleton_type(ft)
875876
f === Core.Intrinsics.llvmcall && return nothing
876877
f === Core.Intrinsics.cglobal && return nothing
877-
878878
atypes = Vector{Any}(undef, length(stmt.args))
879879
atypes[1] = ft
880880
ok = true
@@ -888,7 +888,7 @@ function call_sig(ir::IRCode, stmt::Expr)
888888
end
889889

890890
function inline_apply!(ir::IRCode, idx::Int, sig::Signature, params::OptimizationParams)
891-
stmt = ir.stmts[idx]
891+
stmt = ir.stmts[idx][:inst]
892892
while sig.f === Core._apply || sig.f === Core._apply_iterate
893893
arg_start = sig.f === Core._apply ? 2 : 3
894894
atypes = sig.atypes
@@ -911,7 +911,7 @@ function inline_apply!(ir::IRCode, idx::Int, sig::Signature, params::Optimizatio
911911
break
912912
end
913913
if nonempty_idx != 0
914-
ir.stmts[idx] = stmt.args[nonempty_idx]
914+
ir.stmts[idx][:inst] = stmt.args[nonempty_idx]
915915
return nothing
916916
end
917917
end
@@ -941,8 +941,8 @@ is_builtin(s::Signature) =
941941
s.ft Builtin
942942

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

977977
# Check if we match any of the early inliners
978-
calltype = ir.types[idx]
978+
calltype = ir.stmts[idx][:type]
979979
res = early_inline_special_case(ir, sig, stmt, params, calltype)
980980
if res !== nothing
981-
ir.stmts[idx] = res
981+
ir.stmts[idx][:inst] = res
982982
return nothing
983983
end
984984

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

1016-
stmt = ir.stmts[idx]
1017-
calltype = ir.types[idx]
1016+
stmt = ir.stmts[idx][:inst]
1017+
calltype = ir.stmts[idx][:type]
10181018
(sig, invoke_data) = r
10191019

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

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

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

0 commit comments

Comments
 (0)