Skip to content

Commit 06d432c

Browse files
authored
lowering: Canonicalize to builtins for global assignment (JuliaLang#56713)
This adjusts lowering to emit `setglobal!` for assignment to globals, thus making the `=` expr head used only for slots in `CodeInfo` and entirely absent in `IRCode`. The primary reason for this is just to reduce the number of special cases that compiler passes have to reason about. In IRCode, `=` was already essentially equivalent to `setglobal!`, so there's no good reason not to canonicalize. Finally, the `=` syntax form for globals already gets recognized specially to insert `convert` calls to their declared binding type, so this doesn't impose any additional requirements on lowering to distinguish local from global assignments. In general, I'd also like to separate syntax and intermediate forms as much as possible where their semantics differ, which this accomplises by just using the builtin. This change is mostly semantically invisible, except that spliced-in GlobalRefs now declare their binding because they are indistinguishable from ordinary assignments at the stage where I inserted the lowering. If we want to, we can preserve the difference, but it'd be a bit more annoying for not much benefit, because: 1. The spliced in version was only recently made to work anyway, and 2. The semantics of when exactly bindings are declared is still messy on master anyway and will get tweaked shortly in further binding partitions work.
1 parent ed0636f commit 06d432c

File tree

5 files changed

+5
-38
lines changed

5 files changed

+5
-38
lines changed

src/abstractinterpretation.jl

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4050,13 +4050,7 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState, nextr
40504050
end
40514051
effects === nothing || merge_override_effects!(interp, effects, frame)
40524052
if lhs !== nothing && rt !== Bottom
4053-
if isa(lhs, SlotNumber)
4054-
changes = StateUpdate(lhs, VarState(rt, false))
4055-
elseif isa(lhs, GlobalRef)
4056-
handle_global_assignment!(interp, frame, currsaw_latestworld, lhs, rt)
4057-
else
4058-
merge_effects!(interp, frame, EFFECTS_UNKNOWN)
4059-
end
4053+
changes = StateUpdate(lhs::SlotNumber, VarState(rt, false))
40604054
end
40614055
end
40624056
if !has_curr_ssaflag(frame, IR_FLAG_NOTHROW)

src/optimize.jl

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1408,16 +1408,7 @@ function statement_cost(ex::Expr, line::Int, src::Union{CodeInfo, IRCode}, sptyp
14081408
extyp = line == -1 ? Any : argextype(SSAValue(line), src, sptypes)
14091409
return extyp === Union{} ? 0 : UNKNOWN_CALL_COST
14101410
elseif head === :(=)
1411-
if ex.args[1] isa GlobalRef
1412-
cost = UNKNOWN_CALL_COST
1413-
else
1414-
cost = 0
1415-
end
1416-
a = ex.args[2]
1417-
if a isa Expr
1418-
cost = plus_saturate(cost, statement_cost(a, -1, src, sptypes, params))
1419-
end
1420-
return cost
1411+
return statement_cost(ex.args[2], -1, src, sptypes, params)
14211412
elseif head === :copyast
14221413
return 100
14231414
end

src/ssair/EscapeAnalysis.jl

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -642,13 +642,6 @@ function analyze_escapes(ir::IRCode, nargs::Int, 𝕃ₒ::AbstractLattice, get_e
642642
escape_invoke!(astate, pc, stmt.args)
643643
elseif head === :new || head === :splatnew
644644
escape_new!(astate, pc, stmt.args)
645-
elseif head === :(=)
646-
lhs, rhs = stmt.args
647-
if isa(lhs, GlobalRef) # global store
648-
add_escape_change!(astate, rhs, ⊤)
649-
else
650-
unexpected_assignment!(ir, pc)
651-
end
652645
elseif head === :foreigncall
653646
escape_foreigncall!(astate, pc, stmt.args)
654647
elseif head === :throw_undef_if_not # XXX when is this expression inserted ?
@@ -981,11 +974,6 @@ function escape_unanalyzable_obj!(astate::AnalysisState, @nospecialize(obj), obj
981974
return objinfo
982975
end
983976

984-
@noinline function unexpected_assignment!(ir::IRCode, pc::Int)
985-
@eval Main (ir = $ir; pc = $pc)
986-
error("unexpected assignment found: inspect `Main.pc` and `Main.pc`")
987-
end
988-
989977
is_nothrow(ir::IRCode, pc::Int) = has_flag(ir[SSAValue(pc)], IR_FLAG_NOTHROW)
990978

991979
# NOTE if we don't maintain the alias set that is separated from the lattice state, we can do

src/ssair/verify.jl

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -363,14 +363,8 @@ function verify_ir(ir::IRCode, print::Bool=true,
363363
isforeigncall = false
364364
if isa(stmt, Expr)
365365
if stmt.head === :(=)
366-
if stmt.args[1] isa SSAValue
367-
@verify_error "SSAValue as assignment LHS"
368-
raise_error()
369-
end
370-
if stmt.args[2] isa GlobalRef
371-
# undefined GlobalRef as assignment RHS is OK
372-
continue
373-
end
366+
@verify_error "Assignment should have been removed during SSA conversion"
367+
raise_error()
374368
elseif stmt.head === :isdefined
375369
if length(stmt.args) > 2 || (length(stmt.args) == 2 && !isa(stmt.args[2], Bool))
376370
@verify_error "malformed isdefined"

test/inline.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2111,7 +2111,7 @@ for run_finalizer_escape_test in (run_finalizer_escape_test1, run_finalizer_esca
21112111
global finalizer_escape::Int = 0
21122112

21132113
let src = code_typed1(run_finalizer_escape_test, Tuple{Bool, Bool})
2114-
@test any(x->isexpr(x, :(=)), src.code)
2114+
@test any(iscall((src, Core.setglobal!)), src.code)
21152115
end
21162116

21172117
let

0 commit comments

Comments
 (0)