Skip to content

Commit 64f2dca

Browse files
committed
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 294a574 commit 64f2dca

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
@@ -872,14 +872,15 @@ function perform_lifting!(compact::IncrementalCompact,
872872
return Pair{Any, PhiNest}(stmt_val, PhiNest(visited_philikes, lifted_philikes, lifted_leaves, reverse_mapping, walker_callback))
873873
end
874874

875-
function lift_apply_args!(compact::IncrementalCompact, idx::Int, stmt::Expr, 𝕃ₒ::AbstractLattice)
876-
# Handle _apply_iterate calls: convert arguments to use `Core.svec`. The behavior of Core.svec (with boxing) better matches the ABI of codegen.
875+
# Handle _apply_iterate calls: convert arguments to use `Core.svec`.
876+
# The behavior of `Core.svec` (with boxing) better matches the ABI of codegen.
877+
function lift_apply_args!(compact::IncrementalCompact, idx::Int, stmt::Expr)
877878
compact[idx] = nothing
878-
for i in 4:length(stmt.args) # Skip iterate function, f, and first iterator
879+
for i in 4:length(stmt.args) # Skip `_apply_iterate`, `iterate`, and the function
879880
arg = stmt.args[i]
880-
arg_type = argextype(arg, compact)
881-
svec_args = nothing
881+
arg_type = widenconst(argextype(arg, compact))
882882
if isa(arg_type, DataType) && arg_type.name === Tuple.name
883+
svec_args = nothing
883884
if isa(arg, SSAValue)
884885
arg_stmt = compact[arg][:stmt]
885886
if is_known_call(arg_stmt, Core.tuple, compact)
@@ -900,15 +901,14 @@ function lift_apply_args!(compact::IncrementalCompact, idx::Int, stmt::Expr,
900901
end
901902
end
902903
end
903-
end
904-
# Create Core.svec call if we have arguments
905-
if svec_args !== nothing
906-
svec_args[1] = GlobalRef(Core, :svec)
907-
new_svec_call = Expr(:call)
908-
new_svec_call.args = svec_args
909-
inst = compact[SSAValue(idx)]
910-
new_svec_ssa = insert_node!(compact, SSAValue(idx), NewInstruction(new_svec_call, SimpleVector, NoCallInfo(), inst[:line], inst[:flag]))
911-
stmt.args[i] = new_svec_ssa
904+
if svec_args !== nothing
905+
svec_args[1] = GlobalRef(Core, :svec)
906+
new_svec_call = Expr(:call)
907+
new_svec_call.args = svec_args
908+
inst = compact[SSAValue(idx)]
909+
new_svec_ssa = insert_node!(compact, SSAValue(idx), NewInstruction(new_svec_call, SimpleVector, NoCallInfo(), inst[:line], inst[:flag]))
910+
stmt.args[i] = new_svec_ssa
911+
end
912912
end
913913
end
914914
compact[idx] = stmt
@@ -1420,7 +1420,7 @@ function sroa_pass!(ir::IRCode, inlining::Union{Nothing,InliningState}=nothing)
14201420
refine_new_effects!(𝕃ₒ, compact, idx, stmt)
14211421
elseif is_known_call(stmt, Core._apply_iterate, compact)
14221422
length(stmt.args) >= 4 || continue
1423-
lift_apply_args!(compact, idx, stmt, 𝕃ₒ)
1423+
lift_apply_args!(compact, idx, stmt)
14241424
end
14251425
continue
14261426
end

Compiler/test/irpasses.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2045,3 +2045,17 @@ let src = code_typed1(()) do
20452045
end
20462046
@test count(iscall((src, setfield!)), src.code) == 1
20472047
end
2048+
2049+
# JuliaLang/julia #59548
2050+
# Rewrite `Core._apply_iterate` to use `Core.svec` instead of `tuple` to better match
2051+
# the codegen ABI
2052+
let src = code_typed1((Vector{Any},)) do xs
2053+
println(stdout, xs...)
2054+
end
2055+
@test count(iscall((src, Core.svec)), src.code) == 1
2056+
end
2057+
let src = code_typed1((Vector{Any},)) do xs
2058+
println(stdout, 1, xs...) # convert tuples represented by `PartialStruct`
2059+
end
2060+
@test count(iscall((src, Core.svec)), src.code) == 1
2061+
end

0 commit comments

Comments
 (0)