Skip to content

Commit

Permalink
Merge branch 'master' into jishnub/eigvecs_triangular
Browse files Browse the repository at this point in the history
  • Loading branch information
jishnub authored Sep 6, 2024
2 parents b703c96 + 6f04ee0 commit 9f9c511
Show file tree
Hide file tree
Showing 104 changed files with 2,878 additions and 1,475 deletions.
15 changes: 4 additions & 11 deletions Make.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1095,20 +1095,13 @@ LIBUNWIND:=
else ifneq ($(DISABLE_LIBUNWIND), 0)
LIBUNWIND:=
else
ifeq ($(USE_SYSTEM_LIBUNWIND), 1)
ifneq ($(OS),Darwin)
LIBUNWIND:=-lunwind
# Only for linux since we want to use not yet released libunwind features
JCFLAGS+=-DSYSTEM_LIBUNWIND
JCPPFLAGS+=-DSYSTEM_LIBUNWIND
endif
else
ifneq ($(findstring $(OS),Darwin OpenBSD),)
LIBUNWIND:=-lunwind
JCPPFLAGS+=-DLLVMLIBUNWIND
else
LIBUNWIND:=-lunwind
endif
else ifeq ($(USE_SYSTEM_LIBUNWIND), 1)
# Only for linux and freebsd since we want to use not yet released gnu libunwind features
JCFLAGS+=-DSYSTEM_LIBUNWIND
JCPPFLAGS+=-DSYSTEM_LIBUNWIND
endif
endif

Expand Down
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,9 @@ Standard library changes
* `Profile.take_heap_snapshot` takes a new keyword argument, `redact_data::Bool`,
that is `true` by default. When set, the contents of Julia objects are not emitted
in the heap snapshot. This currently only applies to strings. ([#55326])
* `Profile.print()` now colors Base/Core/Package modules similarly to how they are in stacktraces.
Also paths, even if truncated, are now clickable in terminals that support URI links
to take you to the specified `JULIA_EDITOR` for the given file & line number. ([#55335])

#### Random

Expand Down
6 changes: 3 additions & 3 deletions base/client.jl
Original file line number Diff line number Diff line change
Expand Up @@ -292,12 +292,12 @@ function exec_options(opts)
invokelatest(show, Core.eval(Main, parse_input_line(arg)))
println()
elseif cmd == 'm'
@eval Main import $(Symbol(arg)).main
entrypoint = push!(split(arg, "."), "main")
Base.eval(Main, Expr(:import, Expr(:., Symbol.(entrypoint)...)))
if !should_use_main_entrypoint()
error("`main` in `$arg` not declared as entry point (use `@main` to do so)")
end
return false

elseif cmd == 'L'
# load file immediately on all processors
if !distributed_mode
Expand Down Expand Up @@ -417,7 +417,7 @@ function load_REPL()
return nothing
end

global active_repl
global active_repl::Any
global active_repl_backend = nothing

function run_fallback_repl(interactive::Bool)
Expand Down
66 changes: 41 additions & 25 deletions base/compiler/abstractinterpretation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
arginfo::ArgInfo, si::StmtInfo, @nospecialize(atype),
sv::AbsIntState, max_methods::Int)
𝕃ₚ, 𝕃ᵢ = ipo_lattice(interp), typeinf_lattice(interp)
ₚ, ₚ, = partialorder(𝕃ₚ), join(𝕃ₚ), join(𝕃ᵢ)
ₚ, ₚ, ₚ, = partialorder(𝕃ₚ), strictneqpartialorder(𝕃ₚ), join(𝕃ₚ), join(𝕃ᵢ)
argtypes = arginfo.argtypes
matches = find_method_matches(interp, argtypes, atype; max_methods)
if isa(matches, FailedMethodMatch)
Expand Down Expand Up @@ -97,9 +97,8 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
else
add_remark!(interp, sv, "[constprop] Discarded because the result was wider than inference")
end
if !(exct ₚ const_call_result.exct)
exct = const_call_result.exct
(; const_result, edge) = const_call_result
if const_call_result.exct exct
(; exct, const_result, edge) = const_call_result
else
add_remark!(interp, sv, "[constprop] Discarded exception type because result was wider than inference")
end
Expand Down Expand Up @@ -154,7 +153,7 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
end
# Treat the exception type separately. Currently, constprop often cannot determine the exception type
# because consistent-cy does not apply to exceptions.
if !(this_exct const_call_result.exct)
if const_call_result.exct this_exct
this_exct = const_call_result.exct
(; const_result, edge) = const_call_result
else
Expand Down Expand Up @@ -2135,12 +2134,13 @@ function abstract_invoke(interp::AbstractInterpreter, arginfo::ArgInfo, si::Stmt
(types, isexact, isconcrete, istype) = instanceof_tfunc(argtype_by_index(argtypes, 3), false)
isexact || return CallMeta(Any, Any, Effects(), NoCallInfo())
unwrapped = unwrap_unionall(types)
if types === Bottom || !(unwrapped isa DataType) || unwrapped.name !== Tuple.name
return CallMeta(Bottom, Any, EFFECTS_THROWS, NoCallInfo())
types === Bottom && return CallMeta(Bottom, Any, EFFECTS_THROWS, NoCallInfo())
if !(unwrapped isa DataType && unwrapped.name === Tuple.name)
return CallMeta(Bottom, TypeError, EFFECTS_THROWS, NoCallInfo())
end
argtype = argtypes_to_type(argtype_tail(argtypes, 4))
nargtype = typeintersect(types, argtype)
nargtype === Bottom && return CallMeta(Bottom, Any, EFFECTS_THROWS, NoCallInfo())
nargtype === Bottom && return CallMeta(Bottom, TypeError, EFFECTS_THROWS, NoCallInfo())
nargtype isa DataType || return CallMeta(Any, Any, Effects(), NoCallInfo()) # other cases are not implemented below
isdispatchelem(ft) || return CallMeta(Any, Any, Effects(), NoCallInfo()) # check that we might not have a subtype of `ft` at runtime, before doing supertype lookup below
ft = ft::DataType
Expand All @@ -2154,7 +2154,7 @@ function abstract_invoke(interp::AbstractInterpreter, arginfo::ArgInfo, si::Stmt
tienv = ccall(:jl_type_intersection_with_env, Any, (Any, Any), nargtype, method.sig)::SimpleVector
ti = tienv[1]; env = tienv[2]::SimpleVector
result = abstract_call_method(interp, method, ti, env, false, si, sv)
(; rt, edge, effects, volatile_inf_result) = result
(; rt, exct, edge, effects, volatile_inf_result) = result
match = MethodMatch(ti, env, method, argtype <: method.sig)
res = nothing
sig = match.spec_types
Expand All @@ -2168,20 +2168,28 @@ function abstract_invoke(interp::AbstractInterpreter, arginfo::ArgInfo, si::Stmt
# argtypes′[i] = t ⊑ a ? t : a
# end
𝕃ₚ = ipo_lattice(interp)
, , = partialorder(𝕃ₚ), strictneqpartialorder(𝕃ₚ), join(𝕃ₚ)
f = singleton_type(ft′)
invokecall = InvokeCall(types, lookupsig)
const_call_result = abstract_call_method_with_const_args(interp,
result, f, arginfo, si, match, sv, invokecall)
const_result = volatile_inf_result
if const_call_result !== nothing
if (𝕃ₚ, const_call_result.rt, rt)
if const_call_result.rt rt
(; rt, effects, const_result, edge) = const_call_result
end
if const_call_result.exct exct
(; exct, const_result, edge) = const_call_result
end
end
rt = from_interprocedural!(interp, rt, sv, arginfo, sig)
info = InvokeCallInfo(match, const_result)
edge !== nothing && add_invoke_backedge!(sv, lookupsig, edge)
return CallMeta(rt, Any, effects, info)
if !match.fully_covers
effects = Effects(effects; nothrow=false)
exct = exct TypeError
end
return CallMeta(rt, exct, effects, info)
end

function invoke_rewrite(xs::Vector{Any})
Expand All @@ -2202,16 +2210,16 @@ end

function abstract_throw(interp::AbstractInterpreter, argtypes::Vector{Any}, ::AbsIntState)
na = length(argtypes)
𝕃ᵢ = typeinf_lattice(interp)
= join(typeinf_lattice(interp))
if na == 2
argtype2 = argtypes[2]
if isvarargtype(argtype2)
exct = tmerge(𝕃ᵢ, unwrapva(argtype2), ArgumentError)
exct = unwrapva(argtype2) ArgumentError
else
exct = argtype2
end
elseif na == 3 && isvarargtype(argtypes[3])
exct = tmerge(𝕃ᵢ, argtypes[2], ArgumentError)
exct = argtypes[2] ArgumentError
else
exct = ArgumentError
end
Expand Down Expand Up @@ -2334,35 +2342,43 @@ end
function abstract_call_opaque_closure(interp::AbstractInterpreter,
closure::PartialOpaque, arginfo::ArgInfo, si::StmtInfo, sv::AbsIntState, check::Bool=true)
sig = argtypes_to_type(arginfo.argtypes)
result = abstract_call_method(interp, closure.source::Method, sig, Core.svec(), false, si, sv)
(; rt, edge, effects, volatile_inf_result) = result
tt = closure.typ
sigT = (unwrap_unionall(tt)::DataType).parameters[1]
match = MethodMatch(sig, Core.svec(), closure.source, sig <: rewrap_unionall(sigT, tt))
ocargsig = rewrap_unionall((unwrap_unionall(tt)::DataType).parameters[1], tt)
ocargsig′ = unwrap_unionall(ocargsig)
ocargsig′ isa DataType || return CallMeta(Any, Any, Effects(), NoCallInfo())
ocsig = rewrap_unionall(Tuple{Tuple, ocargsig′.parameters...}, ocargsig)
hasintersect(sig, ocsig) || return CallMeta(Union{}, Union{MethodError,TypeError}, EFFECTS_THROWS, NoCallInfo())
ocmethod = closure.source::Method
result = abstract_call_method(interp, ocmethod, sig, Core.svec(), false, si, sv)
(; rt, exct, edge, effects, volatile_inf_result) = result
match = MethodMatch(sig, Core.svec(), ocmethod, sig <: ocsig)
𝕃ₚ = ipo_lattice(interp)
= (𝕃ₚ)
, , = partialorder(𝕃ₚ), strictneqpartialorder(𝕃ₚ), join(𝕃ₚ)
const_result = volatile_inf_result
if !result.edgecycle
const_call_result = abstract_call_method_with_const_args(interp, result,
nothing, arginfo, si, match, sv)
if const_call_result !== nothing
if const_call_result.rt rt
if const_call_result.rt rt
(; rt, effects, const_result, edge) = const_call_result
end
if const_call_result.exct exct
(; exct, const_result, edge) = const_call_result
end
end
end
if check # analyze implicit type asserts on argument and return type
ftt = closure.typ
(aty, rty) = (unwrap_unionall(ftt)::DataType).parameters
rty = rewrap_unionall(rty isa TypeVar ? rty.lb : rty, ftt)
if !(rt ₚ rty && tuple_tfunc(𝕃ₚ, arginfo.argtypes[2:end]) rewrap_unionall(aty, ftt))
rty = (unwrap_unionall(tt)::DataType).parameters[2]
rty = rewrap_unionall(rty isa TypeVar ? rty.ub : rty, tt)
if !(rt rty && sig ocsig)
effects = Effects(effects; nothrow=false)
exct = exct TypeError
end
end
rt = from_interprocedural!(interp, rt, sv, arginfo, match.spec_types)
info = OpaqueClosureCallInfo(match, const_result)
edge !== nothing && add_backedge!(sv, edge)
return CallMeta(rt, Any, effects, info)
return CallMeta(rt, exct, effects, info)
end

function most_general_argtypes(closure::PartialOpaque)
Expand Down
9 changes: 6 additions & 3 deletions base/compiler/ssair/slot2ssa.jl
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ function fixup_slot!(ir::IRCode, ci::CodeInfo, idx::Int, slot::Int, @nospecializ
insert_node!(ir, idx, NewInstruction(
Expr(:throw_undef_if_not, ci.slotnames[slot], false), Any))
return UNDEF_TOKEN
elseif has_flag(ir.stmts[idx], IR_FLAG_NOTHROW)
# if the `isdefined`-ness of this slot is guaranteed by abstract interpretation,
# there is no need to form a `:throw_undef_if_not`
elseif def_ssa !== true
insert_node!(ir, idx, NewInstruction(
Expr(:throw_undef_if_not, ci.slotnames[slot], def_ssa), Any))
Expand Down Expand Up @@ -153,12 +156,12 @@ end

function fixup_uses!(ir::IRCode, ci::CodeInfo, code::Vector{Any}, uses::Vector{Int}, slot::Int, @nospecialize(ssa))
for use in uses
code[use] = fixemup!(x::SlotNumber->slot_id(x)==slot, stmt::SlotNumber->(ssa, true), ir, ci, use, code[use])
code[use] = fixemup!(x::SlotNumber->slot_id(x)==slot, ::SlotNumber->Pair{Any,Any}(ssa, true), ir, ci, use, code[use])
end
end

function rename_uses!(ir::IRCode, ci::CodeInfo, idx::Int, @nospecialize(stmt), renames::Vector{Pair{Any, Any}})
return fixemup!(stmt::SlotNumber->true, stmt::SlotNumber->renames[slot_id(stmt)], ir, ci, idx, stmt)
return fixemup!(::SlotNumber->true, x::SlotNumber->renames[slot_id(x)], ir, ci, idx, stmt)
end

# maybe use expr_type?
Expand Down Expand Up @@ -656,7 +659,7 @@ function construct_ssa!(ci::CodeInfo, ir::IRCode, sv::OptimizationState,
visited = BitSet()
new_nodes = ir.new_nodes
@timeit "SSA Rename" while !isempty(worklist)
(item::Int, pred, incoming_vals) = pop!(worklist)
(item, pred, incoming_vals) = pop!(worklist)
if sv.bb_vartables[item] === nothing
continue
end
Expand Down
5 changes: 3 additions & 2 deletions base/compiler/typeinfer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -864,7 +864,7 @@ function typeinf_edge(interp::AbstractInterpreter, method::Method, @nospecialize
end
end
if ccall(:jl_get_module_infer, Cint, (Any,), method.module) == 0 && !generating_output(#=incremental=#false)
add_remark!(interp, caller, "Inference is disabled for the target module")
add_remark!(interp, caller, "[typeinf_edge] Inference is disabled for the target module")
return EdgeCallResult(Any, Any, nothing, Effects())
end
if !is_cached(caller) && frame_parent(caller) === nothing
Expand Down Expand Up @@ -897,7 +897,7 @@ function typeinf_edge(interp::AbstractInterpreter, method::Method, @nospecialize
end
frame = InferenceState(result, cache_mode, interp) # always use the cache for edge targets
if frame === nothing
add_remark!(interp, caller, "Failed to retrieve source")
add_remark!(interp, caller, "[typeinf_edge] Failed to retrieve source")
# can't get the source for this, so we know nothing
if cache_mode == CACHE_MODE_GLOBAL
engine_reject(interp, ci)
Expand All @@ -918,6 +918,7 @@ function typeinf_edge(interp::AbstractInterpreter, method::Method, @nospecialize
return EdgeCallResult(frame.bestguess, exc_bestguess, edge, effects, volatile_inf_result)
elseif frame === true
# unresolvable cycle
add_remark!(interp, caller, "[typeinf_edge] Unresolvable cycle")
return EdgeCallResult(Any, Any, nothing, Effects())
end
# return the current knowledge about this cycle
Expand Down
4 changes: 4 additions & 0 deletions base/condition.jl
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ struct GenericCondition{L<:AbstractLock}
GenericCondition(l::AbstractLock) = new{typeof(l)}(IntrusiveLinkedList{Task}(), l)
end

show(io::IO, c::GenericCondition) = print(io, GenericCondition, "(", c.lock, ")")

assert_havelock(c::GenericCondition) = assert_havelock(c.lock)
lock(c::GenericCondition) = lock(c.lock)
unlock(c::GenericCondition) = unlock(c.lock)
Expand Down Expand Up @@ -194,6 +196,8 @@ This object is NOT thread-safe. See [`Threads.Condition`](@ref) for a thread-saf
"""
const Condition = GenericCondition{AlwaysLockedST}

show(io::IO, ::Condition) = print(io, Condition, "()")

lock(c::GenericCondition{AlwaysLockedST}) =
throw(ArgumentError("`Condition` is not thread-safe. Please use `Threads.Condition` instead for multi-threaded code."))
unlock(c::GenericCondition{AlwaysLockedST}) =
Expand Down
34 changes: 29 additions & 5 deletions base/file.jl
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ of the file or directory `src` refers to.
Return `dst`.
!!! note
The `cp` function is different from the `cp` command. The `cp` function always operates on
The `cp` function is different from the `cp` Unix command. The `cp` function always operates on
the assumption that `dst` is a file, while the command does different things depending
on whether `dst` is a directory or a file.
Using `force=true` when `dst` is a directory will result in loss of all the contents present
Expand Down Expand Up @@ -438,6 +438,16 @@ julia> mv("hello.txt", "goodbye.txt", force=true)
julia> rm("goodbye.txt");
```
!!! note
The `mv` function is different from the `mv` Unix command. The `mv` function by
default will error if `dst` exists, while the command will delete
an existing `dst` file by default.
Also the `mv` function always operates on
the assumption that `dst` is a file, while the command does different things depending
on whether `dst` is a directory or a file.
Using `force=true` when `dst` is a directory will result in loss of all the contents present
in the `dst` directory, and `dst` will become a file that has the contents of `src` instead.
"""
function mv(src::AbstractString, dst::AbstractString; force::Bool=false)
if force
Expand Down Expand Up @@ -1183,16 +1193,30 @@ function unlink(p::AbstractString)
end

"""
rename(oldpath::AbstractString, newpath::AbstractString)
Base.rename(oldpath::AbstractString, newpath::AbstractString)
Change the name of a file from `oldpath` to `newpath`. If `newpath` is an existing file it may be replaced.
Equivalent to [rename(2)](https://man7.org/linux/man-pages/man2/rename.2.html).
Throws an `IOError` on failure.
Change the name of a file or directory from `oldpath` to `newpath`.
If `newpath` is an existing file or empty directory it may be replaced.
Equivalent to [rename(2)](https://man7.org/linux/man-pages/man2/rename.2.html) on Unix.
If a path contains a "\\0" throw an `ArgumentError`.
On other failures throw an `IOError`.
Return `newpath`.
This is a lower level filesystem operation used to implement [`mv`](@ref).
OS-specific restrictions may apply when `oldpath` and `newpath` are in different directories.
Currently there are a few differences in behavior on Windows which may be resolved in a future release.
Specifically, currently on Windows:
1. `rename` will fail if `oldpath` or `newpath` are opened files.
2. `rename` will fail if `newpath` is an existing directory.
3. `rename` may work if `newpath` is a file and `oldpath` is a directory.
4. `rename` may remove `oldpath` if it is a hardlink to `newpath`.
See also: [`mv`](@ref).
!!! compat "Julia 1.12"
This method was made public in Julia 1.12.
"""
function rename(oldpath::AbstractString, newpath::AbstractString)
err = ccall(:jl_fs_rename, Int32, (Cstring, Cstring), oldpath, newpath)
Expand Down
14 changes: 14 additions & 0 deletions base/lock.jl
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,20 @@ end

assert_havelock(l::ReentrantLock) = assert_havelock(l, l.locked_by)

show(io::IO, ::ReentrantLock) = print(io, ReentrantLock, "()")

function show(io::IO, ::MIME"text/plain", l::ReentrantLock)
show(io, l)
if !(get(io, :compact, false)::Bool)
locked_by = l.locked_by
if locked_by isa Task
print(io, " (locked by ", locked_by === current_task() ? "current " : "", locked_by, ")")
else
print(io, " (unlocked)")
end
end
end

"""
islocked(lock) -> Status (Boolean)
Expand Down
4 changes: 2 additions & 2 deletions base/opaque_closure.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ the argument type may be fixed length even if the function is variadic.
This interface is experimental and subject to change or removal without notice.
"""
macro opaque(ex)
esc(Expr(:opaque_closure, nothing, nothing, nothing, ex))
esc(Expr(:opaque_closure, nothing, nothing, nothing, #= allow_partial =# true, ex))
end

macro opaque(ty, ex)
Expand All @@ -34,7 +34,7 @@ macro opaque(ty, ex)
end
AT = (AT !== :_) ? AT : nothing
RT = (RT !== :_) ? RT : nothing
return esc(Expr(:opaque_closure, AT, RT, RT, ex))
return esc(Expr(:opaque_closure, AT, RT, RT, #= allow_partial =# true, ex))
end

# OpaqueClosure construction from pre-inferred CodeInfo/IRCode
Expand Down
Loading

0 comments on commit 9f9c511

Please sign in to comment.