Skip to content

Commit a4e02ca

Browse files
authored
optimizations: improve Core._apply_iterate call conversion in #59548 (#59601)
Further improves the implementation from #59548. Specifically, uses `widenconst` to enable conversion of `tuple` calls that have become `PartialStruct`, and removes incorrect comments and unused arguments. Also adds some Julia-IR level tests.
1 parent 81d46eb commit a4e02ca

File tree

2 files changed

+29
-15
lines changed

2 files changed

+29
-15
lines changed

Compiler/src/ssair/passes.jl

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -874,14 +874,15 @@ function perform_lifting!(compact::IncrementalCompact,
874874
return Pair{Any, PhiNest}(stmt_val, PhiNest(visited_philikes, lifted_philikes, lifted_leaves, reverse_mapping, walker_callback))
875875
end
876876

877-
function lift_apply_args!(compact::IncrementalCompact, idx::Int, stmt::Expr, 𝕃ₒ::AbstractLattice)
878-
# Handle _apply_iterate calls: convert arguments to use `Core.svec`. The behavior of Core.svec (with boxing) better matches the ABI of codegen.
877+
# Handle _apply_iterate calls: convert arguments to use `Core.svec`.
878+
# The behavior of `Core.svec` (with boxing) better matches the ABI of codegen.
879+
function lift_apply_args!(compact::IncrementalCompact, idx::Int, stmt::Expr)
879880
compact[idx] = nothing
880-
for i in 4:length(stmt.args) # Skip iterate function, f, and first iterator
881+
for i in 4:length(stmt.args) # Skip `_apply_iterate`, `iterate`, and the function
881882
arg = stmt.args[i]
882-
arg_type = argextype(arg, compact)
883-
svec_args = nothing
883+
arg_type = widenconst(argextype(arg, compact))
884884
if isa(arg_type, DataType) && arg_type.name === Tuple.name
885+
svec_args = nothing
885886
if isa(arg, SSAValue)
886887
arg_stmt = compact[arg][:stmt]
887888
if is_known_call(arg_stmt, Core.tuple, compact)
@@ -902,15 +903,14 @@ function lift_apply_args!(compact::IncrementalCompact, idx::Int, stmt::Expr,
902903
end
903904
end
904905
end
905-
end
906-
# Create Core.svec call if we have arguments
907-
if svec_args !== nothing
908-
svec_args[1] = GlobalRef(Core, :svec)
909-
new_svec_call = Expr(:call)
910-
new_svec_call.args = svec_args
911-
inst = compact[SSAValue(idx)]
912-
new_svec_ssa = insert_node!(compact, SSAValue(idx), NewInstruction(new_svec_call, SimpleVector, NoCallInfo(), inst[:line], inst[:flag]))
913-
stmt.args[i] = new_svec_ssa
906+
if svec_args !== nothing
907+
svec_args[1] = GlobalRef(Core, :svec)
908+
new_svec_call = Expr(:call)
909+
new_svec_call.args = svec_args
910+
inst = compact[SSAValue(idx)]
911+
new_svec_ssa = insert_node!(compact, SSAValue(idx), NewInstruction(new_svec_call, SimpleVector, NoCallInfo(), inst[:line], inst[:flag]))
912+
stmt.args[i] = new_svec_ssa
913+
end
914914
end
915915
end
916916
compact[idx] = stmt
@@ -1422,7 +1422,7 @@ function sroa_pass!(ir::IRCode, inlining::Union{Nothing,InliningState}=nothing)
14221422
refine_new_effects!(𝕃ₒ, compact, idx, stmt)
14231423
elseif is_known_call(stmt, Core._apply_iterate, compact)
14241424
length(stmt.args) >= 4 || continue
1425-
lift_apply_args!(compact, idx, stmt, 𝕃ₒ)
1425+
lift_apply_args!(compact, idx, stmt)
14261426
end
14271427
continue
14281428
end

Compiler/test/irpasses.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2121,3 +2121,17 @@ let src = code_typed1(foosvalconstprop, ())
21212121
end
21222122
@test count(is_constfield_load, src.code) == 0
21232123
end
2124+
2125+
# JuliaLang/julia #59548
2126+
# Rewrite `Core._apply_iterate` to use `Core.svec` instead of `tuple` to better match
2127+
# the codegen ABI
2128+
let src = code_typed1((Vector{Any},)) do xs
2129+
println(stdout, xs...)
2130+
end
2131+
@test count(iscall((src, Core.svec)), src.code) == 1
2132+
end
2133+
let src = code_typed1((Vector{Any},)) do xs
2134+
println(stdout, 1, xs...) # convert tuples represented by `PartialStruct`
2135+
end
2136+
@test count(iscall((src, Core.svec)), src.code) == 1
2137+
end

0 commit comments

Comments
 (0)