Skip to content

Commit fea26dd

Browse files
serenity4Cédric Belmantaviatesk
authored
Optimizer: Update SROA def-uses after DCE (JuliaLang#57201)
Fixes JuliaLang#57141. Given the function ```julia julia> function _f() ref = Ref{Any}() ref[] = 3 @Assert isdefined(ref, :x) inner = Returns(ref) x = inner() (x, ref[]) end _f (generic function with 1 method) julia> f() = first(_f()) f (generic function with 1 method) ``` Here is before: ```julia julia> @code_typed f() CodeInfo( 1 ─ %1 = %new(Base.RefValue{Any})::Base.RefValue{Any} └── goto mmtk#3 2 ─ unreachable 3 ─ return %1 ) => Base.RefValue{Any} ``` Here is after this PR: ```julia julia> @code_typed f() CodeInfo( 1 ─ %1 = %new(Base.RefValue{Any})::Base.RefValue{Any} │ builtin Base.setfield!(%1, :x, 3)::Int64 │ %3 = builtin Main.isdefined(%1, :x)::Bool └── goto mmtk#3 if not %3 2 ─ goto mmtk#4 3 ─ %6 = invoke Base.AssertionError("isdefined(ref, :x)"::String)::AssertionError │ builtin Base.throw(%6)::Union{} └── unreachable 4 ─ return %1 ) => Base.RefValue{Any} ``` The elimination of `setfield!` was due to a use still being recorded for `ref[]` in the def-use data while DCE eliminated this `getindex` call (by virtue of not using the second tuple element in the result). --------- Co-authored-by: Cédric Belmant <cedric.belmant@juliahub.com> Co-authored-by: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com>
1 parent 4bc3206 commit fea26dd

File tree

2 files changed

+16
-0
lines changed

2 files changed

+16
-0
lines changed

Compiler/src/ssair/passes.jl

+4
Original file line numberDiff line numberDiff line change
@@ -1511,6 +1511,10 @@ function sroa_pass!(ir::IRCode, inlining::Union{Nothing,InliningState}=nothing)
15111511
used_ssas[x.id] -= 1
15121512
end
15131513
ir = complete(compact)
1514+
# remove any use that has been optimized away by the DCE
1515+
for (intermediaries, defuse) in values(defuses)
1516+
filter!(x -> ir[SSAValue(x.idx)][:stmt] !== nothing, defuse.uses)
1517+
end
15141518
sroa_mutables!(ir, defuses, used_ssas, lazydomtree, inlining)
15151519
return ir
15161520
else

Compiler/test/irpasses.jl

+12
Original file line numberDiff line numberDiff line change
@@ -2030,3 +2030,15 @@ let code = Any[
20302030
ir = Compiler.domsort_ssa!(ir, domtree)
20312031
Compiler.verify_ir(ir)
20322032
end
2033+
2034+
# https://github.com/JuliaLang/julia/issues/57141
2035+
# don't eliminate `setfield!` when the field is to be used
2036+
let src = code_typed1(()) do
2037+
ref = Ref{Any}()
2038+
ref[] = 0
2039+
@assert isdefined(ref, :x)
2040+
inner() = ref[] + 1
2041+
(inner(), ref[])
2042+
end
2043+
@test count(iscall((src, setfield!)), src.code) == 1
2044+
end

0 commit comments

Comments
 (0)