Skip to content

verify that optimize_until is a valid pass #58033

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions Compiler/src/optimize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -988,14 +988,16 @@ function optimize(interp::AbstractInterpreter, opt::OptimizationState, caller::I
return nothing
end

macro pass(name, expr)
const ALL_PASS_NAMES = String[]
macro pass(name::String, expr)
optimize_until = esc(:optimize_until)
stage = esc(:__stage__)
macrocall = :(@timeit $(esc(name)) $(esc(expr)))
macrocall = :(@timeit $name $(esc(expr)))
macrocall.args[2] = __source__ # `@timeit` may want to use it
push!(ALL_PASS_NAMES, name)
quote
$macrocall
matchpass($optimize_until, ($stage += 1), $(esc(name))) && $(esc(:(@goto __done__)))
matchpass($optimize_until, ($stage += 1), $name) && $(esc(:(@goto __done__)))
end
end

Expand All @@ -1006,8 +1008,13 @@ matchpass(::Nothing, _, _) = false
function run_passes_ipo_safe(
ci::CodeInfo,
sv::OptimizationState,
optimize_until = nothing, # run all passes by default
)
optimize_until::Union{Nothing, Int, String} = nothing) # run all passes by default
if optimize_until isa String && !contains_is(ALL_PASS_NAMES, optimize_until)
error("invalid `optimize_until` argument, no such optimization pass")
elseif optimize_until isa Int && (optimize_until < 1 || optimize_until > length(ALL_PASS_NAMES))
error("invalid `optimize_until` argument, no such optimization pass")
end

__stage__ = 0 # used by @pass
# NOTE: The pass name MUST be unique for `optimize_until::String` to work
@pass "convert" ir = convert_to_ircode(ci, sv)
Expand Down
2 changes: 1 addition & 1 deletion Compiler/test/irpasses.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1459,7 +1459,7 @@ function f_with_early_try_catch_exit()
result
end

let ir = first(only(Base.code_ircode(f_with_early_try_catch_exit, (); optimize_until="compact")))
let ir = first(only(Base.code_ircode(f_with_early_try_catch_exit, (); optimize_until="slot2reg")))
for i = 1:length(ir.stmts)
expr = ir.stmts[i][:stmt]
if isa(expr, PhiCNode)
Expand Down
3 changes: 3 additions & 0 deletions Compiler/test/ssair.jl
Original file line number Diff line number Diff line change
Expand Up @@ -821,3 +821,6 @@ let cl = Int32[32, 1, 1, 1000, 240, 230]
cl2 = ccall(:jl_uncompress_codelocs, Any, (Any, Int), str, 2)
@test cl == cl2
end

@test_throws ErrorException Base.code_ircode(+, (Float64, Float64); optimize_until = "nonexisting pass name")
@test_throws ErrorException Base.code_ircode(+, (Float64, Float64); optimize_until = typemax(Int))
2 changes: 1 addition & 1 deletion test/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2563,7 +2563,7 @@ end
mktemp() do f, io
redirect_stdout(io) do
let io = IOBuffer()
for i = 1:10
for i = 1:length(Base.Compiler.ALL_PASS_NAMES)
# make sure we don't error on printing IRs at any optimization level
ir = only(Base.code_ircode(sin, (Float64,); optimize_until=i))[1]
@test try; show(io, ir); true; catch; false; end
Expand Down