Skip to content

Commit 3684571

Browse files
authored
Merge branch 'master' into js-bump
2 parents 0ee53c4 + a25decd commit 3684571

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+715
-411
lines changed

Compiler/src/ssair/passes.jl

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -874,6 +874,49 @@ 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.
879+
compact[idx] = nothing
880+
for i in 4:length(stmt.args) # Skip iterate function, f, and first iterator
881+
arg = stmt.args[i]
882+
arg_type = argextype(arg, compact)
883+
svec_args = nothing
884+
if isa(arg_type, DataType) && arg_type.name === Tuple.name
885+
if isa(arg, SSAValue)
886+
arg_stmt = compact[arg][:stmt]
887+
if is_known_call(arg_stmt, Core.tuple, compact)
888+
svec_args = copy(arg_stmt.args)
889+
end
890+
end
891+
if svec_args === nothing
892+
# Fallback path: generate getfield calls for tuple elements
893+
tuple_length = length(arg_type.parameters)
894+
if tuple_length > 0 && !isvarargtype(arg_type.parameters[tuple_length])
895+
svec_args = Vector{Any}(undef, tuple_length + 1)
896+
for j in 1:tuple_length
897+
getfield_call = Expr(:call, GlobalRef(Core, :getfield), arg, j)
898+
getfield_type = arg_type.parameters[j]
899+
inst = compact[SSAValue(idx)]
900+
getfield_ssa = insert_node!(compact, SSAValue(idx), NewInstruction(getfield_call, getfield_type, NoCallInfo(), inst[:line], inst[:flag]))
901+
svec_args[j + 1] = getfield_ssa
902+
end
903+
end
904+
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
914+
end
915+
end
916+
compact[idx] = stmt
917+
nothing
918+
end
919+
877920
function lift_svec_ref!(compact::IncrementalCompact, idx::Int, stmt::Expr)
878921
length(stmt.args) != 3 && return
879922

@@ -1377,6 +1420,9 @@ function sroa_pass!(ir::IRCode, inlining::Union{Nothing,InliningState}=nothing)
13771420
compact[SSAValue(idx)] = (compact[enter_ssa][:stmt]::EnterNode).scope
13781421
elseif isexpr(stmt, :new)
13791422
refine_new_effects!(𝕃ₒ, compact, idx, stmt)
1423+
elseif is_known_call(stmt, Core._apply_iterate, compact)
1424+
length(stmt.args) >= 4 || continue
1425+
lift_apply_args!(compact, idx, stmt, 𝕃ₒ)
13801426
end
13811427
continue
13821428
end

Compiler/src/tfuncs.jl

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,15 @@ end
580580
add_tfunc(nfields, 1, 1, nfields_tfunc, 1)
581581
add_tfunc(Core._expr, 1, INT_INF, @nospecs((𝕃::AbstractLattice, args...)->Expr), 100)
582582
add_tfunc(svec, 0, INT_INF, @nospecs((𝕃::AbstractLattice, args...)->SimpleVector), 20)
583+
584+
@nospecs function _svec_len_tfunc(𝕃::AbstractLattice, s)
585+
if isa(s, Const) && isa(s.val, SimpleVector)
586+
return Const(length(s.val))
587+
end
588+
return Int
589+
end
590+
add_tfunc(Core._svec_len, 1, 1, _svec_len_tfunc, 1)
591+
583592
@nospecs function _svec_ref_tfunc(𝕃::AbstractLattice, s, i)
584593
if isa(s, Const) && isa(i, Const)
585594
s, i = s.val, i.val
@@ -1960,15 +1969,8 @@ function tuple_tfunc(𝕃::AbstractLattice, argtypes::Vector{Any})
19601969
# UnionAll context is missing around this.
19611970
pop!(argtypes)
19621971
end
1963-
all_are_const = true
1964-
for i in 1:length(argtypes)
1965-
if !isa(argtypes[i], Const)
1966-
all_are_const = false
1967-
break
1968-
end
1969-
end
1970-
if all_are_const
1971-
return Const(ntuple(i::Int->argtypes[i].val, length(argtypes)))
1972+
if is_all_const_arg(argtypes, 1) # repeated from builtin_tfunction for the benefit of callers that use this tfunc directly
1973+
return Const(tuple(collect_const_args(argtypes, 1)...))
19721974
end
19731975
params = Vector{Any}(undef, length(argtypes))
19741976
anyinfo = false
@@ -2334,14 +2336,17 @@ function _builtin_nothrow(𝕃::AbstractLattice, @nospecialize(f::Builtin), argt
23342336
elseif f === Core.compilerbarrier
23352337
na == 2 || return false
23362338
return compilerbarrier_nothrow(argtypes[1], nothing)
2339+
elseif f === Core._svec_len
2340+
na == 1 || return false
2341+
return _svec_len_tfunc(𝕃, argtypes[1]) isa Const
23372342
elseif f === Core._svec_ref
23382343
na == 2 || return false
23392344
return _svec_ref_tfunc(𝕃, argtypes[1], argtypes[2]) isa Const
23402345
end
23412346
return false
23422347
end
23432348

2344-
# known to be always effect-free (in particular nothrow)
2349+
# known to be always effect-free (in particular also nothrow)
23452350
const _PURE_BUILTINS = Any[
23462351
tuple,
23472352
svec,
@@ -2370,6 +2375,8 @@ const _CONSISTENT_BUILTINS = Any[
23702375
donotdelete,
23712376
memoryrefnew,
23722377
memoryrefoffset,
2378+
Core._svec_len,
2379+
Core._svec_ref,
23732380
]
23742381

23752382
# known to be effect-free (but not necessarily nothrow)
@@ -2394,6 +2401,7 @@ const _EFFECT_FREE_BUILTINS = [
23942401
Core.throw_methoderror,
23952402
getglobal,
23962403
compilerbarrier,
2404+
Core._svec_len,
23972405
Core._svec_ref,
23982406
]
23992407

@@ -2428,6 +2436,7 @@ const _ARGMEM_BUILTINS = Any[
24282436
replacefield!,
24292437
setfield!,
24302438
swapfield!,
2439+
Core._svec_len,
24312440
Core._svec_ref,
24322441
]
24332442

@@ -2571,6 +2580,7 @@ const _EFFECTS_KNOWN_BUILTINS = Any[
25712580
# Core._primitivetype,
25722581
# Core._setsuper!,
25732582
# Core._structtype,
2583+
Core._svec_len,
25742584
Core._svec_ref,
25752585
# Core._typebody!,
25762586
Core._typevar,
@@ -2675,7 +2685,7 @@ function builtin_effects(𝕃::AbstractLattice, @nospecialize(f::Builtin), argty
26752685
else
26762686
if contains_is(_CONSISTENT_BUILTINS, f)
26772687
consistent = ALWAYS_TRUE
2678-
elseif f === memoryrefget || f === memoryrefset! || f === memoryref_isassigned || f === Core._svec_ref
2688+
elseif f === memoryrefget || f === memoryrefset! || f === memoryref_isassigned || f === Core._svec_len || f === Core._svec_ref
26792689
consistent = CONSISTENT_IF_INACCESSIBLEMEMONLY
26802690
elseif f === Core._typevar || f === Core.memorynew
26812691
consistent = CONSISTENT_IF_NOTRETURNED
@@ -2784,11 +2794,12 @@ end
27842794
function builtin_tfunction(interp::AbstractInterpreter, @nospecialize(f), argtypes::Vector{Any},
27852795
sv::Union{AbsIntState, Nothing})
27862796
𝕃ᵢ = typeinf_lattice(interp)
2787-
if isa(f, IntrinsicFunction)
2788-
if is_pure_intrinsic_infer(f) && all(@nospecialize(a) -> isa(a, Const), argtypes)
2789-
argvals = anymap(@nospecialize(a) -> (a::Const).val, argtypes)
2797+
# Early constant evaluation for foldable builtins with all const args
2798+
if isa(f, IntrinsicFunction) ? is_pure_intrinsic_infer(f) : (f in _PURE_BUILTINS || (f in _CONSISTENT_BUILTINS && f in _EFFECT_FREE_BUILTINS))
2799+
if is_all_const_arg(argtypes, 1)
2800+
argvals = collect_const_args(argtypes, 1)
27902801
try
2791-
# unroll a few cases which have specialized codegen
2802+
# unroll a few common cases for better codegen
27922803
if length(argvals) == 1
27932804
return Const(f(argvals[1]))
27942805
elseif length(argvals) == 2
@@ -2802,6 +2813,8 @@ function builtin_tfunction(interp::AbstractInterpreter, @nospecialize(f), argtyp
28022813
return Bottom
28032814
end
28042815
end
2816+
end
2817+
if isa(f, IntrinsicFunction)
28052818
iidx = Int(reinterpret(Int32, f)) + 1
28062819
if iidx < 0 || iidx > length(T_IFUNC)
28072820
# unknown intrinsic
@@ -2828,6 +2841,7 @@ function builtin_tfunction(interp::AbstractInterpreter, @nospecialize(f), argtyp
28282841
end
28292842
tf = T_FFUNC_VAL[fidx]
28302843
end
2844+
28312845
if hasvarargtype(argtypes)
28322846
if length(argtypes) - 1 > tf[2]
28332847
# definitely too many arguments

Compiler/test/codegen.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,14 +134,14 @@ if !is_debug_build && opt_level > 0
134134
# Array
135135
test_loads_no_call(strip_debug_calls(get_llvm(sizeof, Tuple{Vector{Int}})), [Iptr])
136136
# As long as the eltype is known we don't need to load the elsize, but do need to check isvector
137-
@test_skip test_loads_no_call(strip_debug_calls(get_llvm(sizeof, Tuple{Array{Any}})), ["atomic $Iptr", "ptr", "ptr", Iptr, Iptr, "ptr", Iptr])
137+
@test_skip test_loads_no_call(strip_debug_calls(get_llvm(sizeof, Tuple{Array{Any}})), ["atomic volatile $Iptr", "ptr", "ptr", Iptr, Iptr, "ptr", Iptr])
138138
# Memory
139139
test_loads_no_call(strip_debug_calls(get_llvm(core_sizeof, Tuple{Memory{Int}})), [Iptr])
140140
# As long as the eltype is known we don't need to load the elsize
141141
test_loads_no_call(strip_debug_calls(get_llvm(core_sizeof, Tuple{Memory{Any}})), [Iptr])
142142
# Check that we load the elsize and isunion from the typeof layout
143-
test_loads_no_call(strip_debug_calls(get_llvm(core_sizeof, Tuple{Memory})), [Iptr, "atomic $Iptr", "ptr", "i32", "i16"])
144-
test_loads_no_call(strip_debug_calls(get_llvm(core_sizeof, Tuple{Memory})), [Iptr, "atomic $Iptr", "ptr", "i32", "i16"])
143+
test_loads_no_call(strip_debug_calls(get_llvm(core_sizeof, Tuple{Memory})), [Iptr, "atomic volatile $Iptr", "ptr", "i32", "i16"])
144+
test_loads_no_call(strip_debug_calls(get_llvm(core_sizeof, Tuple{Memory})), [Iptr, "atomic volatile $Iptr", "ptr", "i32", "i16"])
145145
# Primitive Type size should be folded to a constant
146146
test_loads_no_call(strip_debug_calls(get_llvm(core_sizeof, Tuple{Ptr})), String[])
147147

Compiler/test/effects.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1474,7 +1474,7 @@ end
14741474
let effects = Base.infer_effects((Core.SimpleVector,Int); optimize=false) do svec, i
14751475
Core._svec_ref(svec, i)
14761476
end
1477-
@test !Compiler.is_consistent(effects)
1477+
@test Compiler.is_consistent(effects)
14781478
@test Compiler.is_effect_free(effects)
14791479
@test !Compiler.is_nothrow(effects)
14801480
@test Compiler.is_terminates(effects)

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ and then use the command prompt to change into the resulting julia directory. By
9797
Julia. However, most users should use the [most recent stable version](https://github.com/JuliaLang/julia/releases)
9898
of Julia. You can get this version by running:
9999

100-
git checkout v1.11.6
100+
git checkout v1.11.7
101101

102102
To build the `julia` executable, run `make` from within the julia directory.
103103

base/Base.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ using .Filesystem
180180
include("cmd.jl")
181181
include("process.jl")
182182
include("terminfo.jl")
183+
include("Terminals.jl") # Moved from REPL to reduce invalidations
183184
include("secretbuffer.jl")
184185

185186
# core math functions
File renamed without changes.

base/c.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,6 @@ macro ccall(exprs...)
458458
return ccall_macro_lower((:ccall), ccall_macro_parse(exprs)...)
459459
end
460460

461-
macro ccall_effects(effects::UInt16, expr)
462-
return ccall_macro_lower((:ccall, effects), ccall_macro_parse(expr)...)
461+
macro ccall_effects(effects::UInt16, exprs...)
462+
return ccall_macro_lower((:ccall, effects), ccall_macro_parse(exprs)...)
463463
end

base/char.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ represents a valid Unicode character.
4747
"""
4848
Char
4949

50-
@constprop :aggressive (::Type{T})(x::Number) where {T<:AbstractChar} = T(UInt32(x))
50+
@constprop :aggressive (::Type{T})(x::Number) where {T<:AbstractChar} = T(UInt32(x)::UInt32)
5151
@constprop :aggressive AbstractChar(x::Number) = Char(x)
5252
@constprop :aggressive (::Type{T})(x::AbstractChar) where {T<:Union{Number,AbstractChar}} = T(codepoint(x))
5353
@constprop :aggressive (::Type{T})(x::AbstractChar) where {T<:Union{Int32,Int64}} = codepoint(x) % T
@@ -225,9 +225,9 @@ hash(x::Char, h::UInt) =
225225
hash_finalizer(((bitcast(UInt32, x) + UInt64(0xd4d64234)) << 32) UInt64(h)) % UInt
226226

227227
# fallbacks:
228-
isless(x::AbstractChar, y::AbstractChar) = isless(Char(x), Char(y))
229-
==(x::AbstractChar, y::AbstractChar) = Char(x) == Char(y)
230-
hash(x::AbstractChar, h::UInt) = hash(Char(x), h)
228+
isless(x::AbstractChar, y::AbstractChar) = isless(Char(x)::Char, Char(y)::Char)
229+
==(x::AbstractChar, y::AbstractChar) = Char(x)::Char == Char(y)::Char
230+
hash(x::AbstractChar, h::UInt) = hash(Char(x)::Char, h)
231231
widen(::Type{T}) where {T<:AbstractChar} = T
232232

233233
@inline -(x::AbstractChar, y::AbstractChar) = Int(x) - Int(y)
@@ -257,7 +257,7 @@ end
257257
# (Packages may implement other IO subtypes to specify different encodings.)
258258
# In contrast, `write(io, c)` outputs a `c` in an encoding determined by typeof(c).
259259
print(io::IO, c::Char) = (write(io, c); nothing)
260-
print(io::IO, c::AbstractChar) = print(io, Char(c)) # fallback: convert to output UTF-8
260+
print(io::IO, c::AbstractChar) = print(io, Char(c)::Char) # fallback: convert to output UTF-8
261261

262262
const hex_chars = UInt8['0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
263263
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',

base/essentials.jl

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -979,11 +979,7 @@ setindex!(A::MemoryRef{Any}, @nospecialize(x)) = (memoryrefset!(A, x, :not_atomi
979979

980980
getindex(v::SimpleVector, i::Int) = (@_foldable_meta; Core._svec_ref(v, i))
981981
function length(v::SimpleVector)
982-
@_total_meta
983-
t = @_gc_preserve_begin v
984-
len = unsafe_load(Ptr{Int}(pointer_from_objref(v)))
985-
@_gc_preserve_end t
986-
return len
982+
Core._svec_len(v)
987983
end
988984
firstindex(v::SimpleVector) = 1
989985
lastindex(v::SimpleVector) = length(v)

0 commit comments

Comments
 (0)