Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
9e91b68
update utf8proc to 2.11.3 (#60207)
stevengj Dec 31, 2025
7dd0882
Fix many instances of `Core.Box` in Base. (#60515)
KristofferC Jan 3, 2026
34e04ab
Remove many `Core.Box` in stdlibs and Base. (#60490)
KristofferC Dec 29, 2025
0fc1f94
Avoid more `Core.Box` in Base (and Compiler) (#60547)
KristofferC Jan 7, 2026
7928de9
avoid some more `Core.Box` in Base and SharedArrays (#60599)
KristofferC Jan 9, 2026
0fedb1c
bump StyledStrings to latest release-1.13
KristofferC Jan 9, 2026
1e8985d
🤖 [backports-release-1.13] Bump Downloads stdlib 4e20d02 → f72cd4d (#…
DilumAluthgeBot Jan 10, 2026
3fb442e
🤖 [backports-release-1.13] Bump Tar stdlib 9dd8ed1 → 10e4e96 (#60616)
DilumAluthgeBot Jan 10, 2026
1a8597c
🤖 [backports-release-1.13] Bump SparseArrays stdlib 26c80c8 → 6b7e9ef…
DilumAluthgeBot Jan 15, 2026
4c1b9d9
[1.13] Backport #60718+#60746: Fix and test `jl_method_lookup_by_tt` …
maleadt Jan 20, 2026
4099572
[1.13] Fix `codeinfo_for_const` missing `nargs` and `isva` fields (#6…
maleadt Jan 24, 2026
1bb37ce
Fix build with USE_SYSTEM_P7ZIP=1 (#60623)
nhz2 Jan 11, 2026
3a10a01
Preserve the scope across the exception handler (#60647)
vchuravy Jan 14, 2026
a3972ac
Fix @fastmath x^2 inlining regression for Float32 and Float16 (#60640)
Yashagarwal9798 Jan 14, 2026
3314ac7
Fix JET warnings in `show(::IOBuffer, ::StackFrame)` (#60645)
lgoettgens Jan 14, 2026
8c85653
Don't set the owner of the string needlessly. (#60601)
gbaraldi Jan 14, 2026
d1e35de
add wb_back on all task switch paths (#60617)
vtjnash Jan 15, 2026
791a72e
Don't include NI tags when verifying external module data layouts. (#…
maleadt Jan 17, 2026
cefa626
Revert "Revert "Enable getting non-boxed LLVM type from Julia Type" (…
wsmoses Jan 19, 2026
c0565df
Temporarily reintroduce a global type inference lock (#60689)
xal-0 Jan 20, 2026
50f61d0
llvm: Fix alloca alignment and type selection in AllocOpt (#60699)
gbaraldi Jan 21, 2026
00737ca
Add optimizer support for `invoke(f, ::CodeInstance, args...)` (#60442)
MasonProtter Jan 24, 2026
b6549ab
bindings: Define behavior of `using` an ambiguous binding (#60804)
Keno Jan 24, 2026
3a047b7
compiler/ssair: preserve negative NewSSAValue (#60688)
KristofferC Jan 29, 2026
3feb3be
Fix typo in partially_inline! (#60854)
oscardssmith Jan 29, 2026
06de0f3
ssair: fix phi edge cleanup for current block (#60697)
KristofferC Jan 29, 2026
281b06d
inference: fix union split handling for custom lattices (#60857)
aviatesk Jan 29, 2026
a42e47b
Merge pull request #60834 from rokke-git/patch-5
rokke-git Jan 28, 2026
60cbee4
OpenBLAS: Update to 0.30.0 (#60789)
eschnett Jan 23, 2026
50febfa
Move precompilation during package loading behind `@invokelatest` (#6…
JamesWrigley Jan 26, 2026
28b6dc0
Make `jl_reinit_foreign_type` idempotent even with asserts (#60827)
fingolfin Jan 27, 2026
2588817
make sure `jl_exit_threaded_region` executed when `threading_run` fin…
songjhaha Jan 29, 2026
ddd05b5
OpenSSL: Update to 3.5.5 (#60875)
eschnett Jan 30, 2026
4b9d0fd
Artifacts stdlib: Add `TOML` and `Pkg` as test dependencies (#60891)
DilumAluthge Feb 1, 2026
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
14 changes: 13 additions & 1 deletion Compiler/src/ssair/inlining.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1164,8 +1164,20 @@ end
function handle_invoke_call!(todo::Vector{Pair{Int,Any}},
ir::IRCode, idx::Int, stmt::Expr, @nospecialize(info), flag::UInt32,
sig::Signature, state::InliningState)
# InvokeCICallInfo indicates that `abstract_invoke` already analyzed the call
# and determined it is of the form `invoke(f, ::CodeInstance, args...)`
# where the argtypes and worldages are valid for the context, and the invoke
# pointer is set. Therefore, we can simply transform this into an
# `Expr(:invoke, ...)`
if info isa InvokeCICallInfo
stmt.head = :invoke
stmt.args = [info.edge, stmt.args[2], stmt.args[4:end]...]
# Transformed to :invoke, now handle it as such
handle_invoke_expr!(todo, ir, idx, stmt, info, flag, sig, state)
return nothing
end
nspl = nsplit(info)
nspl == 0 && return nothing # e.g. InvokeCICallInfo
nspl == 0 && return nothing
@assert nspl == 1
mresult = getsplit(info, 1)
match = mresult.matches[1]
Expand Down
31 changes: 23 additions & 8 deletions Compiler/src/ssair/ir.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1382,8 +1382,19 @@ function kill_edge!(ir::IRCode, from::Int, to::Int, callback=nothing)
kill_edge!(ir.cfg.blocks, from, to, callback)
end

# N.B.: from and to are non-renamed indices
function kill_edge!(compact::IncrementalCompact, active_bb::Int, from::Int, to::Int)
@inline function compacted_stmt_range(compact::IncrementalCompact, bb::BasicBlock, active_bb::Int, to::Int)
to == active_bb && return StmtRange(first(bb.stmts), compact.result_idx - 1)
return bb.stmts
end

"""
kill_edge_terminator!(compact::IncrementalCompact, active_bb::Int, from::Int, to::Int)

Kill a CFG edge while compacting a terminator in `active_bb`. Assumes all PhiNode
block statements in `to` have already been processed, so the active BB may only
scan the compacted prefix when `to == active_bb`. `from` and `to` are non-renamed indices.
"""
function kill_edge_terminator!(compact::IncrementalCompact, active_bb::Int, from::Int, to::Int)
# Note: We recursively kill as many edges as are obviously dead.
(; bb_rename_pred, bb_rename_succ, result_bbs, domtree) = compact.cfg_transform
preds = result_bbs[bb_rename_succ[to]].preds
Expand All @@ -1399,7 +1410,7 @@ function kill_edge!(compact::IncrementalCompact, active_bb::Int, from::Int, to::
for succ in copy(to_succs)
new_succ = findfirst(x::Int->x==succ, bb_rename_pred)
new_succ === nothing && continue
kill_edge!(compact, active_bb, to, new_succ)
kill_edge_terminator!(compact, active_bb, to, new_succ)
end
empty!(preds)
empty!(to_succs)
Expand All @@ -1421,8 +1432,9 @@ function kill_edge!(compact::IncrementalCompact, active_bb::Int, from::Int, to::
# Remove this edge from all phi nodes in `to` block
# NOTE: It is possible for `to` to contain only `nothing` statements,
# so we must be careful to stop at its last statement
if to < active_bb
stmts = result_bbs[bb_rename_succ[to]].stmts
if to <= active_bb
bb = result_bbs[bb_rename_succ[to]]
stmts = compacted_stmt_range(compact, bb, active_bb, to)
idx = first(stmts)
while idx <= last(stmts)
stmt = compact.result[idx][:stmt]
Expand Down Expand Up @@ -1502,14 +1514,14 @@ function process_node!(compact::IncrementalCompact, result_idx::Int, inst::Instr
if cond
ssa_rename[idx] = nothing
result[result_idx][:stmt] = nothing
kill_edge!(compact, active_bb, active_bb, stmt.dest)
kill_edge_terminator!(compact, active_bb, active_bb, stmt.dest)
# Don't increment result_idx => Drop this statement
else
label = bb_rename_succ[stmt.dest]
@assert label > 0
ssa_rename[idx] = SSAValue(result_idx)
result[result_idx][:stmt] = GotoNode(label)
kill_edge!(compact, active_bb, active_bb, active_bb+1)
kill_edge_terminator!(compact, active_bb, active_bb, active_bb+1)
result_idx += 1
end
else
Expand Down Expand Up @@ -1684,7 +1696,10 @@ function process_node!(compact::IncrementalCompact, result_idx::Int, inst::Instr
stmt = ssa_rename[stmt.id]
end
elseif isa(stmt, NewSSAValue)
stmt = SSAValue(stmt.id)
if stmt.id > 0
# Negative ids reference new_new_nodes and must remain NewSSAValue.
stmt = SSAValue(stmt.id)
end
else
# Constant assign, replace uses of this ssa value with its result
end
Expand Down
72 changes: 42 additions & 30 deletions Compiler/src/ssair/passes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -361,20 +361,25 @@ function already_inserted(compact::IncrementalCompact, old::OldSSAValue)
already_inserted_ssa(compact, compact.idx-1)(0, old)
end

function already_inserted_ssa(compact::IncrementalCompact, processed_idx::Int)
return function did_already_insert(phi_arg::Int, old::OldSSAValue)
id = old.id
if id <= length(compact.ir.stmts)
return id <= processed_idx
end
id -= length(compact.ir.stmts)
if id <= length(compact.ir.new_nodes)
return did_already_insert(phi_arg, OldSSAValue(compact.ir.new_nodes.info[id].pos))
end
id -= length(compact.ir.new_nodes)
@assert id <= length(compact.pending_nodes)
return !(id in compact.pending_perm)
function _already_inserted_ssa(compact::IncrementalCompact, processed_idx::Int,
phi_arg::Int, old::OldSSAValue)
id = old.id
if id <= length(compact.ir.stmts)
return id <= processed_idx
end
id -= length(compact.ir.stmts)
if id <= length(compact.ir.new_nodes)
return _already_inserted_ssa(compact, processed_idx, phi_arg,
OldSSAValue(compact.ir.new_nodes.info[id].pos))
end
id -= length(compact.ir.new_nodes)
@assert id <= length(compact.pending_nodes)
return !(id in compact.pending_perm)
end

function already_inserted_ssa(compact::IncrementalCompact, processed_idx::Int)
return (phi_arg::Int, old::OldSSAValue) ->
_already_inserted_ssa(compact, processed_idx, phi_arg, old)
end

function is_pending(compact::IncrementalCompact, old::OldSSAValue)
Expand Down Expand Up @@ -1644,6 +1649,25 @@ function reachable_blocks(cfg::CFG, from_bb::Int, to_bb::Int)
return visited
end

function _update_finalizer_insert!(ir::IRCode, lazypostdomtree::LazyPostDomtree,
finalizer_idx::Int, insert_bb::Int,
insert_idx::Union{Int,Nothing}, x::Union{Int,SSAUse})
defuse_idx = x isa SSAUse ? x.idx : x
defuse_idx == finalizer_idx && return insert_bb, insert_idx
defuse_bb = block_for_inst(ir, defuse_idx)
new_insert_bb = nearest_common_dominator(get!(lazypostdomtree),
insert_bb, defuse_bb)
if new_insert_bb == insert_bb && insert_idx !== nothing
insert_idx = max(insert_idx::Int, defuse_idx)
elseif new_insert_bb == defuse_bb
insert_idx = defuse_idx
else
insert_idx = nothing
end
insert_bb = new_insert_bb
return insert_bb, insert_idx
end

function try_resolve_finalizer!(ir::IRCode, alloc_idx::Int, finalizer_idx::Int, defuse::SSADefUse,
inlining::InliningState, lazydomtree::LazyDomtree,
lazypostdomtree::LazyPostDomtree, @nospecialize(info::CallInfo))
Expand All @@ -1665,24 +1689,12 @@ function try_resolve_finalizer!(ir::IRCode, alloc_idx::Int, finalizer_idx::Int,
# Check #2: The insertion block for the finalizer is the post-dominator of all uses
insert_bb::Int = finalizer_bb
insert_idx::Union{Int,Nothing} = finalizer_idx
function note_defuse!(x::Union{Int,SSAUse})
defuse_idx = x isa SSAUse ? x.idx : x
defuse_idx == finalizer_idx && return nothing
defuse_bb = block_for_inst(ir, defuse_idx)
new_insert_bb = nearest_common_dominator(get!(lazypostdomtree),
insert_bb, defuse_bb)
if new_insert_bb == insert_bb && insert_idx !== nothing
insert_idx = max(insert_idx::Int, defuse_idx)
elseif new_insert_bb == defuse_bb
insert_idx = defuse_idx
else
insert_idx = nothing
end
insert_bb = new_insert_bb
nothing
for x in defuse.uses
insert_bb, insert_idx = _update_finalizer_insert!(ir, lazypostdomtree, finalizer_idx, insert_bb, insert_idx, x)
end
for x in defuse.defs
insert_bb, insert_idx = _update_finalizer_insert!(ir, lazypostdomtree, finalizer_idx, insert_bb, insert_idx, x)
end
foreach(note_defuse!, defuse.uses)
foreach(note_defuse!, defuse.defs)
insert_bb != 0 || return nothing # verify post-dominator of all uses exists

if !OptimizationParams(inlining.interp).assume_fatal_throw
Expand Down
165 changes: 85 additions & 80 deletions Compiler/src/ssair/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -534,37 +534,33 @@ function DILineInfoPrinter(debuginfo, def, showtypes::Bool=false)
started::Bool = false
if !update_line_only && showtypes && !isa(frame.method, Symbol) && nctx != 1
print(io, linestart)
with_output_color(linecolor, io) do io
print(io, indent("│"))
print(io, "┌ invoke ", frame.method)
println(io)
end
printstyled(io, indent("│"), color=linecolor)
printstyled(io, "┌ invoke ", frame.method, color=linecolor)
println(io)
started = true
end
print(io, linestart)
with_output_color(linecolor, io) do io
print(io, indent("│"))
push!(context, frame)
if update_line_only
update_line_only = false
else
context_depth[] += 1
nctx != 1 && print(io, started ? "│" : "┌")
end
print(io, " @ ", frame.file)
if frame.line != typemax(frame.line) && frame.line != 0
print(io, ":", frame.line)
end
print(io, " within `", method_name(frame), "`")
if collapse
method = method_name(frame)
while nctx < nframes
frame = DI[nframes - nctx]
method_name(frame) === method || break
nctx += 1
push!(context, frame)
print(io, " @ ", frame.file, ":", frame.line)
end
printstyled(io, indent("│"), color=linecolor)
push!(context, frame)
if update_line_only
update_line_only = false
else
context_depth[] += 1
nctx != 1 && printstyled(io, started ? "│" : "┌", color=linecolor)
end
printstyled(io, " @ ", frame.file, color=linecolor)
if frame.line != typemax(frame.line) && frame.line != 0
printstyled(io, ":", frame.line, color=linecolor)
end
printstyled(io, " within `", method_name(frame), "`", color=linecolor)
if collapse
method = method_name(frame)
while nctx < nframes
frame = DI[nframes - nctx]
method_name(frame) === method || break
nctx += 1
push!(context, frame)
printstyled(io, " @ ", frame.file, ":", frame.line, color=linecolor)
end
end
println(io)
Expand Down Expand Up @@ -681,6 +677,60 @@ function show_ir_stmt(io::IO, code::Union{IRCode, CodeInfo, IncrementalCompact},
sptypes, used, cfg, bb_idx; pop_new_node!, only_after, config.bb_color, config.label_dynamic_calls)
end

function _print_ir_indentation(io::IO, cfg::CFG, bb_idx::Int, max_bb_idx_size::Int, bb_color,
line_info_preprinter, idx::Int, i::Int; final::Bool=true)
# Compute BB guard rail
if bb_idx > length(cfg.blocks)
# If invariants are violated, print a special leader
linestart = " "^(max_bb_idx_size + 2) # not inside a basic block bracket
inlining_indent = line_info_preprinter(io, linestart, i == 1 ? idx : 0)
printstyled(io, "!!! ", "─"^max_bb_idx_size, color=bb_color)
else
bbrange = cfg.blocks[bb_idx].stmts
# Print line info update
linestart = idx == first(bbrange) ? " " : sprint(io -> printstyled(io, "│ ", color=bb_color), context=io)
linestart *= " "^max_bb_idx_size
# idx == 0 means only indentation is printed, so we don't print linfos
# multiple times if the are new nodes
inlining_indent = line_info_preprinter(io, linestart, i == 1 ? idx : 0)

if i == 1 && idx == first(bbrange)
bb_idx_str = string(bb_idx)
bb_pad = max_bb_idx_size - length(bb_idx_str)
bb_type = length(cfg.blocks[bb_idx].preds) <= 1 ? "─" : "┄"
printstyled(io, bb_idx_str, " ", bb_type, "─"^bb_pad, color=bb_color)
elseif final && idx == last(bbrange) # print separator
printstyled(io, "└", "─"^(1 + max_bb_idx_size), color=bb_color)
else
printstyled(io, "│ ", " "^max_bb_idx_size, color=bb_color)
end
end
print(io, inlining_indent, " ")
return nothing
end

function _print_ir_new_node(io::IO, node, code, sptypes::Vector{VarState}, used::BitSet, maxlength_idx::Int,
label_dynamic_calls::Bool, line_info_postprinter, cfg::CFG, bb_idx::Int,
max_bb_idx_size::Int, bb_color, line_info_preprinter, idx::Int, i::Int; final::Bool=true)
_print_ir_indentation(io, cfg, bb_idx, max_bb_idx_size, bb_color, line_info_preprinter, idx, i; final)

node_idx, new_node_inst, new_node_type = node
@assert new_node_inst !== UNDEF # we filtered these out earlier
show_type = should_print_ssa_type(new_node_inst)
with_output_color(:green, io) do io′
print_stmt(io′, node_idx, new_node_inst, code, sptypes, used, maxlength_idx, false, show_type, label_dynamic_calls)
end

if new_node_type === UNDEF
# Try to be robust against errors
printstyled(io, "::#UNDEF", color=:red)
else
line_info_postprinter(io; type = new_node_type, used = node_idx in used, show_type, idx = node_idx)
end
println(io)
return nothing
end

function show_ir_stmt(io::IO, code::Union{IRCode, CodeInfo, IncrementalCompact}, idx::Int, line_info_preprinter, line_info_postprinter,
sptypes::Vector{VarState}, used::BitSet, cfg::CFG, bb_idx::Int; pop_new_node! = Returns(nothing), only_after::Bool=false,
bb_color=:light_black, label_dynamic_calls::Bool=true)
Expand All @@ -703,58 +753,11 @@ function show_ir_stmt(io::IO, code::Union{IRCode, CodeInfo, IncrementalCompact},
end

i = 1
function print_indentation(final::Bool=true)
# Compute BB guard rail
if bb_idx > length(cfg.blocks)
# If invariants are violated, print a special leader
linestart = " "^(max_bb_idx_size + 2) # not inside a basic block bracket
inlining_indent = line_info_preprinter(io, linestart, i == 1 ? idx : 0)
printstyled(io, "!!! ", "─"^max_bb_idx_size, color=bb_color)
else
bbrange = cfg.blocks[bb_idx].stmts
# Print line info update
linestart = idx == first(bbrange) ? " " : sprint(io -> printstyled(io, "│ ", color=bb_color), context=io)
linestart *= " "^max_bb_idx_size
# idx == 0 means only indentation is printed, so we don't print linfos
# multiple times if the are new nodes
inlining_indent = line_info_preprinter(io, linestart, i == 1 ? idx : 0)

if i == 1 && idx == first(bbrange)
bb_idx_str = string(bb_idx)
bb_pad = max_bb_idx_size - length(bb_idx_str)
bb_type = length(cfg.blocks[bb_idx].preds) <= 1 ? "─" : "┄"
printstyled(io, bb_idx_str, " ", bb_type, "─"^bb_pad, color=bb_color)
elseif final && idx == last(bbrange) # print separator
printstyled(io, "└", "─"^(1 + max_bb_idx_size), color=bb_color)
else
printstyled(io, "│ ", " "^max_bb_idx_size, color=bb_color)
end
end
print(io, inlining_indent, " ")
end

# first, print new nodes that are to be inserted before the current statement
function print_new_node(node; final::Bool=true)
print_indentation(final)

node_idx, new_node_inst, new_node_type = node
@assert new_node_inst !== UNDEF # we filtered these out earlier
show_type = should_print_ssa_type(new_node_inst)
let maxlength_idx=maxlength_idx, show_type=show_type
with_output_color(:green, io) do io′
print_stmt(io′, node_idx, new_node_inst, code, sptypes, used, maxlength_idx, false, show_type, label_dynamic_calls)
end
end

if new_node_type === UNDEF # try to be robust against errors
printstyled(io, "::#UNDEF", color=:red)
else
line_info_postprinter(io; type = new_node_type, used = node_idx in used, show_type, idx = node_idx)
end
println(io)
end
while (next = pop_new_node!(idx)) !== nothing
only_after || print_new_node(next; final=false)
only_after || _print_ir_new_node(io, next, code, sptypes, used, maxlength_idx, label_dynamic_calls,
line_info_postprinter, cfg, bb_idx, max_bb_idx_size, bb_color,
line_info_preprinter, idx, i; final=false)
i += 1
end

Expand All @@ -766,7 +769,7 @@ function show_ir_stmt(io::IO, code::Union{IRCode, CodeInfo, IncrementalCompact},
# FIXME: `only_after` is hack so that we can call this function to print uncompacted
# attach-after nodes when the current node has already been compated already
if !only_after
print_indentation(next===nothing)
_print_ir_indentation(io, cfg, bb_idx, max_bb_idx_size, bb_color, line_info_preprinter, idx, i; final=next===nothing)
if code isa CodeInfo
stmt = statement_indices_to_labels(stmt, cfg)
end
Expand All @@ -786,7 +789,9 @@ function show_ir_stmt(io::IO, code::Union{IRCode, CodeInfo, IncrementalCompact},

# finally, print new nodes that are to be inserted after the current statement
while next !== nothing
print_new_node(next)
_print_ir_new_node(io, next, code, sptypes, used, maxlength_idx, label_dynamic_calls,
line_info_postprinter, cfg, bb_idx, max_bb_idx_size, bb_color,
line_info_preprinter, idx, i)
i += 1
next = pop_new_node!(idx; attach_after=true)
end
Expand Down
Loading
Loading