Skip to content

Commit

Permalink
Merge branch 'master' into stdlib-backlinks
Browse files Browse the repository at this point in the history
  • Loading branch information
LilithHafner authored Jan 14, 2024
2 parents bb25629 + 681816c commit 729b1b1
Show file tree
Hide file tree
Showing 38 changed files with 362 additions and 231 deletions.
2 changes: 1 addition & 1 deletion base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -881,7 +881,7 @@ julia> empty([1.0, 2.0, 3.0], String)
String[]
```
"""
empty(a::AbstractVector{T}, ::Type{U}=T) where {T,U} = Vector{U}()
empty(a::AbstractVector{T}, ::Type{U}=T) where {T,U} = similar(a, U, 0)

# like empty, but should return a mutable collection, a Vector by default
emptymutable(a::AbstractVector{T}, ::Type{U}=T) where {T,U} = Vector{U}()
Expand Down
2 changes: 1 addition & 1 deletion base/compiler/inferencestate.jl
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@ function InferenceState(result::InferenceResult, cache_mode::UInt8, interp::Abst
world = get_world_counter(interp)
src = retrieve_code_info(result.linfo, world)
src === nothing && return nothing
validate_code_in_debug_mode(result.linfo, src, "lowered")
maybe_validate_code(result.linfo, src, "lowered")
return InferenceState(result, src, cache_mode, interp)
end
InferenceState(result::InferenceResult, cache_mode::Symbol, interp::AbstractInterpreter) =
Expand Down
11 changes: 7 additions & 4 deletions base/compiler/optimize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ function ir_to_codeinf!(opt::OptimizationState)
(; linfo, src) = opt
src = ir_to_codeinf!(src, opt.ir::IRCode)
opt.ir = nothing
validate_code_in_debug_mode(linfo, src, "optimized")
maybe_validate_code(linfo, src, "optimized")
return src
end

Expand Down Expand Up @@ -934,8 +934,11 @@ function run_passes_ipo_safe(
if made_changes
@pass "compact 3" ir = compact!(ir, true)
end
if JLOptions().debug_level == 2
@timeit "verify 3" (verify_ir(ir, true, false, optimizer_lattice(sv.inlining.interp)); verify_linetable(ir.linetable))
if is_asserts()
@timeit "verify 3" begin
verify_ir(ir, true, false, optimizer_lattice(sv.inlining.interp))
verify_linetable(ir.linetable)
end
end
@label __done__ # used by @pass
return ir
Expand Down Expand Up @@ -1056,7 +1059,7 @@ function convert_to_ircode(ci::CodeInfo, sv::OptimizationState)
ssaflags[block_end] = IR_FLAG_NOTHROW

# Verify that type-inference did its job
if JLOptions().debug_level == 2
if is_asserts()
for i = (oldidx + 1):last(sv.cfg.blocks[block].stmts)
@assert i in sv.unreachable
end
Expand Down
23 changes: 18 additions & 5 deletions base/compiler/ssair/domtree.jl
Original file line number Diff line number Diff line change
Expand Up @@ -82,21 +82,25 @@ struct DFSTree
# (preorder number -> preorder number)
# Storing it this way saves a few lookups in the snca_compress! algorithm
to_parent_pre::Vector{PreNumber}

_worklist::Vector{Tuple{BBNumber, PreNumber, Bool}}
end

function DFSTree(n_blocks::Int)
return DFSTree(zeros(PreNumber, n_blocks),
Vector{BBNumber}(undef, n_blocks),
zeros(PostNumber, n_blocks),
Vector{BBNumber}(undef, n_blocks),
zeros(PreNumber, n_blocks))
zeros(PreNumber, n_blocks),
Vector{Tuple{BBNumber, PreNumber, Bool}}())
end

copy(D::DFSTree) = DFSTree(copy(D.to_pre),
copy(D.from_pre),
copy(D.to_post),
copy(D.from_post),
copy(D.to_parent_pre))
copy(D.to_parent_pre),
copy(D._worklist))

function copy!(dst::DFSTree, src::DFSTree)
copy!(dst.to_pre, src.to_pre)
Expand All @@ -106,17 +110,26 @@ function copy!(dst::DFSTree, src::DFSTree)
copy!(dst.to_parent_pre, src.to_parent_pre)
return dst
end
function resize!(D::DFSTree, n::Integer)
resize!(D.to_pre, n)
resize!(D.from_pre, n)
resize!(D.to_post, n)
resize!(D.from_post, n)
resize!(D.to_parent_pre, n)
end

length(D::DFSTree) = length(D.from_pre)

function DFS!(D::DFSTree, blocks::Vector{BasicBlock}, is_post_dominator::Bool)
copy!(D, DFSTree(length(blocks)))
resize!(D, length(blocks))
fill!(D.to_pre, 0)
to_visit = D._worklist # always starts empty
if is_post_dominator
# TODO: We're using -1 as the virtual exit node here. Would it make
# sense to actually have a real BB for the exit always?
to_visit = Tuple{BBNumber, PreNumber, Bool}[(-1, 0, false)]
push!(to_visit, (-1, 0, false))
else
to_visit = Tuple{BBNumber, PreNumber, Bool}[(1, 0, false)]
push!(to_visit, (1, 0, false))
end
pre_num = is_post_dominator ? 0 : 1
post_num = 1
Expand Down
20 changes: 13 additions & 7 deletions base/compiler/ssair/passes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1403,7 +1403,7 @@ function sroa_pass!(ir::IRCode, inlining::Union{Nothing,InliningState}=nothing)
(lifted_val, nest) = perform_lifting!(compact,
visited_philikes, field, result_t, lifted_leaves, val, lazydomtree)

node_was_deleted = false
should_delete_node = false
line = compact[SSAValue(idx)][:line]
if lifted_val !== nothing && !⊑(𝕃ₒ, compact[SSAValue(idx)][:type], result_t)
compact[idx] = lifted_val === nothing ? nothing : lifted_val.val
Expand All @@ -1412,9 +1412,8 @@ function sroa_pass!(ir::IRCode, inlining::Union{Nothing,InliningState}=nothing)
# Save some work in a later compaction, by inserting this into the renamer now,
# but only do this if we didn't set the REFINED flag, to save work for irinterp
# in revisiting only the renamings that came through *this* idx.
delete_inst_here!(compact)
compact.ssa_rename[old_idx] = lifted_val === nothing ? nothing : lifted_val.val
node_was_deleted = true
should_delete_node = true
else
compact[idx] = lifted_val === nothing ? nothing : lifted_val.val
end
Expand All @@ -1435,17 +1434,24 @@ function sroa_pass!(ir::IRCode, inlining::Union{Nothing,InliningState}=nothing)
def_val = (def_val::LiftedValue).val
finish_phi_nest!(compact, nest)
end
ni = NewInstruction(
Expr(:throw_undef_if_not, Symbol("##getfield##"), def_val), Nothing, line)
if node_was_deleted
insert_node_here!(compact, ni, true)
throw_expr = Expr(:throw_undef_if_not, Symbol("##getfield##"), def_val)
if should_delete_node
# Replace the node we already have rather than deleting/re-inserting.
# This way it is easier to handle BB boundary corner cases.
compact[SSAValue(idx)] = throw_expr
compact[SSAValue(idx)][:type] = Nothing
compact[SSAValue(idx)][:flag] = IR_FLAG_EFFECT_FREE | IR_FLAG_CONSISTENT | IR_FLAG_NOUB
should_delete_node = false
else
ni = NewInstruction(throw_expr, Nothing, line)
insert_node!(compact, SSAValue(idx), ni)
end
else
# val must be defined
@assert lifted_val !== nothing
end

should_delete_node && delete_inst_here!(compact)
end

non_dce_finish!(compact)
Expand Down
2 changes: 1 addition & 1 deletion base/compiler/typeinfer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,7 @@ function finish(me::InferenceState, interp::AbstractInterpreter)
end
end

validate_code_in_debug_mode(me.linfo, me.src, "inferred")
maybe_validate_code(me.linfo, me.src, "inferred")
nothing
end

Expand Down
4 changes: 4 additions & 0 deletions base/compiler/utilities.jl
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,7 @@ end
is_root_module(m::Module) = false

inlining_enabled() = (JLOptions().can_inline == 1)

function coverage_enabled(m::Module)
generating_output() && return false # don't alter caches
cov = JLOptions().code_coverage
Expand All @@ -533,9 +534,12 @@ function coverage_enabled(m::Module)
end
return false
end

function inbounds_option()
opt_check_bounds = JLOptions().check_bounds
opt_check_bounds == 0 && return :default
opt_check_bounds == 1 && return :on
return :off
end

is_asserts() = ccall(:jl_is_assertsbuild, Cint, ()) == 1
6 changes: 3 additions & 3 deletions base/compiler/validation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,8 @@ struct InvalidCodeError <: Exception
end
InvalidCodeError(kind::AbstractString) = InvalidCodeError(kind, nothing)

function validate_code_in_debug_mode(linfo::MethodInstance, src::CodeInfo, kind::String)
if JLOptions().debug_level == 2
# this is a debug build of julia, so let's validate linfo
function maybe_validate_code(linfo::MethodInstance, src::CodeInfo, kind::String)
if is_asserts()
errors = validate_code(linfo, src)
if !isempty(errors)
for e in errors
Expand All @@ -75,6 +74,7 @@ function validate_code_in_debug_mode(linfo::MethodInstance, src::CodeInfo, kind:
linfo.def, ": ", e)
end
end
error("")
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion base/complex.jl
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,7 @@ end
"""
cis(x)

More efficient method for `exp(im*x)` by using Euler's formula: ``cos(x) + i sin(x) = \\exp(i x)``.
More efficient method for `exp(im*x)` by using Euler's formula: ``\\cos(x) + i \\sin(x) = \\exp(i x)``.

See also [`cispi`](@ref), [`sincos`](@ref), [`exp`](@ref), [`angle`](@ref).

Expand Down
5 changes: 5 additions & 0 deletions base/loading.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1033,8 +1033,13 @@ function cache_file_entry(pkg::PkgId)
uuid === nothing ? pkg.name : package_slug(uuid)
end

# for use during running the REPL precompilation subprocess script, given we don't
# want it to pick up caches that already exist for other optimization levels
const ignore_compiled_cache = PkgId[]

function find_all_in_cache_path(pkg::PkgId)
paths = String[]
pkg in ignore_compiled_cache && return paths
entrypath, entryfile = cache_file_entry(pkg)
for path in joinpath.(DEPOT_PATH, entrypath)
isdir(path) || continue
Expand Down
3 changes: 3 additions & 0 deletions base/lock.jl
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,9 @@ end
```
This is similar to using [`lock`](@ref) with a `do` block, but avoids creating a closure
and thus can improve the performance.

!!! compat
`@lock` was added in Julia 1.3, and exported in Julia 1.10.
"""
macro lock(l, expr)
quote
Expand Down
99 changes: 2 additions & 97 deletions base/stacktraces.jl
Original file line number Diff line number Diff line change
Expand Up @@ -97,87 +97,6 @@ function hash(frame::StackFrame, h::UInt)
return h
end

get_inlinetable(::Any) = nothing
function get_inlinetable(mi::MethodInstance)
isdefined(mi, :def) && mi.def isa Method && isdefined(mi, :cache) && isdefined(mi.cache, :inferred) &&
mi.cache.inferred !== nothing || return nothing
linetable = ccall(:jl_uncompress_ir, Any, (Any, Any, Any), mi.def, mi.cache, mi.cache.inferred).linetable
return filter!(x -> x.inlined_at > 0, linetable)
end

get_method_instance_roots(::Any) = nothing
function get_method_instance_roots(mi::Union{Method, MethodInstance})
m = mi isa MethodInstance ? mi.def : mi
m isa Method && isdefined(m, :roots) || return nothing
return filter(x -> x isa MethodInstance, m.roots)
end

function lookup_inline_frame_info(func::Symbol, file::Symbol, linenum::Int, inlinetable::Vector{Core.LineInfoNode})
#REPL frames and some base files lack this prefix while others have it; should fix?
filestripped = Symbol(lstrip(string(file), ('.', '\\', '/')))
linfo = nothing
#=
Some matching entries contain the MethodInstance directly.
Other matching entries contain only a Method or Symbol (function name); such entries
are located after the entry with the MethodInstance, so backtracking is required.
If backtracking fails, the Method or Module is stored for return, but we continue
the search in case a MethodInstance is found later.
TODO: If a backtrack has failed, do we need to backtrack again later if another Method
or Symbol match is found? Or can a limit on the subsequent backtracks be placed?
=#
for (i, line) in enumerate(inlinetable)
Base.IRShow.method_name(line) === func && line.file ∈ (file, filestripped) && line.line == linenum || continue
if line.method isa MethodInstance
linfo = line.method
break
elseif line.method isa Method || line.method isa Symbol
linfo = line.method isa Method ? line.method : line.module
# backtrack to find the matching MethodInstance, if possible
for j in (i - 1):-1:1
nextline = inlinetable[j]
nextline.inlined_at == line.inlined_at && Base.IRShow.method_name(line) === Base.IRShow.method_name(nextline) && line.file === nextline.file || break
if nextline.method isa MethodInstance
linfo = nextline.method
break
end
end
end
end
return linfo
end

function lookup_inline_frame_info(func::Symbol, file::Symbol, miroots::Vector{Any})
# REPL frames and some base files lack this prefix while others have it; should fix?
filestripped = Symbol(lstrip(string(file), ('.', '\\', '/')))
matches = filter(miroots) do x
x.def isa Method || return false
m = x.def::Method
return m.name == func && m.file ∈ (file, filestripped)
end
if length(matches) > 1
# ambiguous, check if method is same and return that instead
all_matched = true
for m in matches
all_matched = m.def.line == matches[1].def.line &&
m.def.module == matches[1].def.module
all_matched || break
end
if all_matched
return matches[1].def
end
# all else fails, return module if they match, or give up
all_matched = true
for m in matches
all_matched = m.def.module == matches[1].def.module
all_matched || break
end
return all_matched ? matches[1].def.module : nothing
elseif length(matches) == 1
return matches[1]
end
return nothing
end

"""
lookup(pointer::Ptr{Cvoid}) -> Vector{StackFrame}

Expand All @@ -189,25 +108,11 @@ Base.@constprop :none function lookup(pointer::Ptr{Cvoid})
infos = ccall(:jl_lookup_code_address, Any, (Ptr{Cvoid}, Cint), pointer, false)::Core.SimpleVector
pointer = convert(UInt64, pointer)
isempty(infos) && return [StackFrame(empty_sym, empty_sym, -1, nothing, true, false, pointer)] # this is equal to UNKNOWN
parent_linfo = infos[end][4]
inlinetable = get_inlinetable(parent_linfo)
miroots = inlinetable === nothing ? get_method_instance_roots(parent_linfo) : nothing # fallback if linetable missing
res = Vector{StackFrame}(undef, length(infos))
for i in reverse(1:length(infos))
for i in 1:length(infos)
info = infos[i]::Core.SimpleVector
@assert(length(info) == 6)
func = info[1]::Symbol
file = info[2]::Symbol
linenum = info[3]::Int
linfo = info[4]
if i < length(infos)
if inlinetable !== nothing
linfo = lookup_inline_frame_info(func, file, linenum, inlinetable)
elseif miroots !== nothing
linfo = lookup_inline_frame_info(func, file, miroots)
end
end
res[i] = StackFrame(func, file, linenum, linfo, info[5]::Bool, info[6]::Bool, pointer)
res[i] = StackFrame(info[1]::Symbol, info[2]::Symbol, info[3]::Int, info[4], info[5]::Bool, info[6]::Bool, pointer)
end
return res
end
Expand Down
2 changes: 1 addition & 1 deletion base/uuid.jl
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ let groupings = [36:-1:25; 23:-1:20; 18:-1:15; 13:-1:10; 8:-1:1]
end

print(io::IO, u::UUID) = print(io, string(u))
show(io::IO, u::UUID) = print(io, "UUID(\"", u, "\")")
show(io::IO, u::UUID) = print(io, UUID, "(\"", u, "\")")

isless(a::UUID, b::UUID) = isless(a.value, b.value)

Expand Down
6 changes: 6 additions & 0 deletions contrib/generate_precompile.jl
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ precompile(Tuple{typeof(Base.hashindex), String, Int64})
precompile(Tuple{typeof(Base.write), Base.GenericIOBuffer{Array{UInt8, 1}}, String})
precompile(Tuple{typeof(Base.indexed_iterate), Tuple{Nothing, Int64}, Int64})
precompile(Tuple{typeof(Base.indexed_iterate), Tuple{Nothing, Int64}, Int64, Int64})
precompile(Tuple{typeof(Base._typeddict), Base.Dict{String, Any}, Base.Dict{String, Any}, Vararg{Base.Dict{String, Any}}})
precompile(Tuple{typeof(Base.promoteK), Type, Base.Dict{String, Any}, Base.Dict{String, Any}})
precompile(Tuple{typeof(Base.promoteK), Type, Base.Dict{String, Any}})
precompile(Tuple{typeof(Base.promoteV), Type, Base.Dict{String, Any}, Base.Dict{String, Any}})
precompile(Tuple{typeof(Base.eval_user_input), Base.PipeEndpoint, Any, Bool})
precompile(Tuple{typeof(Base.get), Base.PipeEndpoint, Symbol, Bool})

# used by Revise.jl
precompile(Tuple{typeof(Base.parse_cache_header), String})
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
97bb33510fadec7f4cc4c718c739e9a0
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
a362aaf762f42deebb8632a7a7980cd22b2777e8c4dc629e418580269e24a64217ad846d61acad70438cfdc190e47ba2ff7716edd4e04d8d10c1d765efce604d
2 changes: 2 additions & 0 deletions deps/csl.mk
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ install-csl:
cp -a $(build_libdir)/gcc/$(BB_TRIPLET)/13/libgcc.a $(build_private_libdir)/
cp -a $(build_libdir)/gcc/$(BB_TRIPLET)/13/libmsvcrt.a $(build_private_libdir)/
cp -a $(build_libdir)/gcc/$(BB_TRIPLET)/13/libssp.dll.a $(build_private_libdir)/
cp -a $(build_libdir)/gcc/$(BB_TRIPLET)/13/libssp.dll.a $(build_libdir)/
endif
endif
ifeq ($(OS),WINNT)
Expand All @@ -120,4 +121,5 @@ uninstall-gcc-libraries:
-rm -f $(build_private_libdir)/libgcc.a
-rm -f $(build_private_libdir)/libmsvcrt.a
-rm -f $(build_private_libdir)/libssp.dll.a
-rm -f $(build_libdir)/libssp.dll.a
endif
Loading

0 comments on commit 729b1b1

Please sign in to comment.