Skip to content

Commit 400e7d8

Browse files
committed
optimizer: handle GlobalRef based on assume_bindings_static
Following up #53750. External abstract interpreters with `assume_bindings_static` enabled assume nothrow-ness of defined `GlobalRef`s no matter if they are constant during abstract interpretation. However, post-#53750, the optimizer’s verification switched to stricter checks, causing errors in such interpreters. This commit makes `IRCode` hold `assume_bindings_static::Bool` info to ensure that inlining and verification behaviors are synced with abstract interpretation.
1 parent 2ca9e00 commit 400e7d8

File tree

4 files changed

+31
-19
lines changed

4 files changed

+31
-19
lines changed

base/compiler/abstractinterpretation.jl

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2842,7 +2842,7 @@ function abstract_eval_globalref(interp::AbstractInterpreter, g::GlobalRef, sv::
28422842
rt = abstract_eval_globalref_type(g)
28432843
consistent = inaccessiblememonly = ALWAYS_FALSE
28442844
nothrow = false
2845-
if isa(rt, Const)
2845+
if isa(rt, Const) # implies `isdefinedconst_globalref(g) === true`
28462846
consistent = ALWAYS_TRUE
28472847
nothrow = true
28482848
if is_mutation_free_argtype(rt)
@@ -2855,8 +2855,6 @@ function abstract_eval_globalref(interp::AbstractInterpreter, g::GlobalRef, sv::
28552855
else
28562856
rt = Union{}
28572857
end
2858-
elseif isdefinedconst_globalref(g)
2859-
nothrow = true
28602858
end
28612859
return RTEffects(rt, nothrow ? Union{} : UndefVarError, Effects(EFFECTS_TOTAL; consistent, nothrow, inaccessiblememonly))
28622860
end

base/compiler/optimize.jl

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,9 @@ function new_expr_effect_flags(𝕃ₒ::AbstractLattice, args::Vector{Any}, src:
286286
return (false, true, true)
287287
end
288288

289+
assume_bindings_static(ir::IRCode) = ir.assume_bindings_static
290+
assume_bindings_static(compact::IncrementalCompact) = assume_bindings_static(compact.ir)
291+
289292
"""
290293
stmt_effect_flags(stmt, rt, src::Union{IRCode,IncrementalCompact}) ->
291294
(consistent::Bool, removable::Bool, nothrow::Bool)
@@ -301,7 +304,12 @@ function stmt_effect_flags(𝕃ₒ::AbstractLattice, @nospecialize(stmt), @nospe
301304
isa(stmt, GotoNode) && return (true, false, true)
302305
isa(stmt, GotoIfNot) && return (true, false, (𝕃ₒ, argextype(stmt.cond, src), Bool))
303306
if isa(stmt, GlobalRef)
304-
nothrow = consistent = isdefinedconst_globalref(stmt)
307+
if assume_bindings_static(src)
308+
nothrow = isdefined_globalref(stmt)
309+
consistent = nothrow & isconst(stmt)
310+
else
311+
nothrow = consistent = isdefinedconst_globalref(stmt)
312+
end
305313
return (consistent, nothrow, nothrow)
306314
elseif isa(stmt, Expr)
307315
(; head, args) = stmt
@@ -1131,7 +1139,6 @@ function convert_to_ircode(ci::CodeInfo, sv::OptimizationState)
11311139
# Go through and add an unreachable node after every
11321140
# Union{} call. Then reindex labels.
11331141
stmtinfo = sv.stmt_info
1134-
meta = Expr[]
11351142
idx = 1
11361143
oldidx = 1
11371144
nstmts = length(code)
@@ -1231,25 +1238,28 @@ function convert_to_ircode(ci::CodeInfo, sv::OptimizationState)
12311238
renumber_cfg_stmts!(sv.cfg, blockchangemap)
12321239
end
12331240

1234-
for i = 1:length(code)
1235-
code[i] = process_meta!(meta, code[i])
1236-
end
1241+
meta = process_meta!(code)
12371242
strip_trailing_junk!(code, ssavaluetypes, ssaflags, di, sv.cfg, stmtinfo)
12381243
types = Any[]
12391244
stmts = InstructionStream(code, types, stmtinfo, codelocs, ssaflags)
12401245
# NOTE this `argtypes` contains types of slots yet: it will be modified to contain the
12411246
# types of call arguments only once `slot2reg` converts this `IRCode` to the SSA form
12421247
# and eliminates slots (see below)
12431248
argtypes = sv.slottypes
1244-
return IRCode(stmts, sv.cfg, di, argtypes, meta, sv.sptypes)
1249+
return IRCode(stmts, sv.cfg, di, argtypes, meta, sv.sptypes,
1250+
InferenceParams(sv.inlining.interp).assume_bindings_static)
12451251
end
12461252

1247-
function process_meta!(meta::Vector{Expr}, @nospecialize stmt)
1248-
if isexpr(stmt, :meta) && length(stmt.args) 1
1249-
push!(meta, stmt)
1250-
return nothing
1253+
function process_meta!(code::Vector{Any})
1254+
meta = Expr[]
1255+
for i = 1:length(code)
1256+
stmt = code[i]
1257+
if isexpr(stmt, :meta) && length(stmt.args) 1
1258+
push!(meta, stmt)
1259+
code[i] = nothing
1260+
end
12511261
end
1252-
return stmt
1262+
return meta
12531263
end
12541264

12551265
function slot2reg(ir::IRCode, ci::CodeInfo, sv::OptimizationState)

base/compiler/ssair/ir.jl

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -428,22 +428,26 @@ struct IRCode
428428
cfg::CFG
429429
new_nodes::NewNodeStream
430430
meta::Vector{Expr}
431+
assume_bindings_static::Bool # XXX propagate `interp::AbstractInterpreter` here?
431432

432-
function IRCode(stmts::InstructionStream, cfg::CFG, debuginfo::DebugInfoStream, argtypes::Vector{Any}, meta::Vector{Expr}, sptypes::Vector{VarState})
433-
return new(stmts, argtypes, sptypes, debuginfo, cfg, NewNodeStream(), meta)
433+
function IRCode(stmts::InstructionStream, cfg::CFG, debuginfo::DebugInfoStream,
434+
argtypes::Vector{Any}, meta::Vector{Expr}, sptypes::Vector{VarState},
435+
assume_bindings_static::Bool=false)
436+
return new(stmts, argtypes, sptypes, debuginfo, cfg, NewNodeStream(), meta, assume_bindings_static)
434437
end
435438
function IRCode(ir::IRCode, stmts::InstructionStream, cfg::CFG, new_nodes::NewNodeStream)
436439
di = ir.debuginfo
437440
@assert di.codelocs === stmts.line
438-
return new(stmts, ir.argtypes, ir.sptypes, di, cfg, new_nodes, ir.meta)
441+
return new(stmts, ir.argtypes, ir.sptypes, di, cfg, new_nodes, ir.meta, ir.assume_bindings_static)
439442
end
440443
global function copy(ir::IRCode)
441444
di = ir.debuginfo
442445
stmts = copy(ir.stmts)
443446
di = copy(di)
444447
di.edges = copy(di.edges)
445448
di.codelocs = stmts.line
446-
return new(stmts, copy(ir.argtypes), copy(ir.sptypes), di, copy(ir.cfg), copy(ir.new_nodes), copy(ir.meta))
449+
return new(stmts, copy(ir.argtypes), copy(ir.sptypes), di, copy(ir.cfg),
450+
copy(ir.new_nodes), copy(ir.meta), ir.assume_bindings_static)
447451
end
448452
end
449453

base/compiler/ssair/verify.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ function check_op(ir::IRCode, domtree::DomTree, @nospecialize(op), use_bb::Int,
5656
error("")
5757
end
5858
elseif isa(op, GlobalRef)
59-
if !isdefined(op.mod, op.name) || !isconst(op.mod, op.name)
59+
if !(assume_bindings_static(ir) ? isdefined_globalref(op) : isdefinedconst_globalref(op))
6060
@verify_error "Unbound GlobalRef not allowed in value position"
6161
error("")
6262
end

0 commit comments

Comments
 (0)