Skip to content

Commit

Permalink
Merge branch 'master' into revert-inline-lookup
Browse files Browse the repository at this point in the history
  • Loading branch information
BioTurboNick authored Jan 12, 2024
2 parents beddd2c + 5b6a94d commit 05c6909
Show file tree
Hide file tree
Showing 128 changed files with 2,617 additions and 1,376 deletions.
2 changes: 1 addition & 1 deletion Make.inc
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ JCPPFLAGS_COMMON := -fasynchronous-unwind-tables
JCPPFLAGS_CLANG := $(JCPPFLAGS_COMMON) -mllvm -enable-tail-merge=0
JCPPFLAGS_GCC := $(JCPPFLAGS_COMMON) -fno-tree-tail-merge

JCXXFLAGS_COMMON := -pipe $(fPIC) -fno-rtti -std=c++14
JCXXFLAGS_COMMON := -pipe $(fPIC) -fno-rtti -std=c++17
JCXXFLAGS_CLANG := $(JCXXFLAGS_COMMON) -pedantic
JCXXFLAGS_GCC := $(JCXXFLAGS_COMMON) -fno-gnu-unique

Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ else ifeq ($(JULIA_BUILD_MODE),debug)
JL_PRIVATE_LIBS-0 += libjulia-internal-debug libjulia-codegen-debug
endif
ifeq ($(USE_GPL_LIBS), 1)
JL_PRIVATE_LIBS-$(USE_SYSTEM_LIBSUITESPARSE) += libamd libbtf libcamd libccolamd libcholmod libcholmod_cuda libcolamd libklu libldl librbio libspqr libspqr_cuda libsuitesparseconfig libumfpack
JL_PRIVATE_LIBS-$(USE_SYSTEM_LIBSUITESPARSE) += libamd libbtf libcamd libccolamd libcholmod libcolamd libklu libldl librbio libspqr libsuitesparseconfig libumfpack
endif
JL_PRIVATE_LIBS-$(USE_SYSTEM_LIBBLASTRAMPOLINE) += libblastrampoline
JL_PRIVATE_LIBS-$(USE_SYSTEM_PCRE) += libpcre2-8
Expand Down
5 changes: 4 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,10 @@ Standard library changes
* `eigvals/eigen(A, bunchkaufman(B))` and `eigvals/eigen(A, lu(B))`, which utilize the Bunchkaufman (LDL) and LU decomposition of `B`,
respectively, now efficiently compute the generalized eigenvalues (`eigen`: and eigenvectors) of `A` and `B`. Note: The second
argument is the output of `bunchkaufman` or `lu` ([#50471]).
* There is now a specialized dispatch for `eigvals/eigen(::Hermitian{<:Tridiagonal})` which performs a similarity transformation to create a real symmetrix triagonal matrix, and solve that using the LAPACK routines ([#49546]).
* Structured matrices now retain either the axes of the parent (for `Symmetric`/`Hermitian`/`AbstractTriangular`/`UpperHessenberg`), or that of the principal diagonal (for banded matrices) ([#52480]).
* `bunchkaufman` and `bunchkaufman!` now work for any `AbstractFloat`, `Rational` and their complex variants. `bunchkaufman` now supports `Integer` types, by making an internal conversion to `Rational{BigInt}`. Added new function `inertia` that computes the inertia of the diagonal factor given by the `BunchKaufman` factorization object of a real symmetric or Hermitian matrix. For complex symmetric matrices, `inertia` only computes the number of zero eigenvalues of the diagonal factor ([#51487]).
* Packages that specialize matrix-matrix `mul!` with a method signature of the form `mul!(::AbstractMatrix, ::MyMatrix, ::AbstractMatrix, ::Number, ::Number)` no longer encounter method ambiguities when interacting with `LinearAlgebra`. Previously, ambiguities used to arise when multiplying a `MyMatrix` with a structured matrix type provided by LinearAlgebra, such as `AbstractTriangular`, which used to necessitate additional methods to resolve such ambiguities. Similar sources of ambiguities have also been removed for matrix-vector `mul!` operations ([#52837]).

#### Logging
* New `@create_log_macro` macro for creating new log macros like `@info`, `@warn` etc. For instance
Expand All @@ -138,7 +140,8 @@ Standard library changes

* Tab complete hints now show in lighter text while typing in the repl. To disable
set `Base.active_repl.options.hint_tab_completes = false` ([#51229]).
* Meta-M with an empty prompt now returns the contextual module of the REPL to `Main`.
* Meta-M with an empty prompt now toggles the contextual module between the previous non-Main
contextual module and Main so that switching back and forth is simple. ([#51616], [#52670])

#### SuiteSparse

Expand Down
2 changes: 0 additions & 2 deletions base/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -269,11 +269,9 @@ $(eval $(call symlink_system_library,LIBSUITESPARSE,libamd))
$(eval $(call symlink_system_library,LIBSUITESPARSE,libcamd))
$(eval $(call symlink_system_library,LIBSUITESPARSE,libccolamd))
$(eval $(call symlink_system_library,LIBSUITESPARSE,libcholmod))
$(eval $(call symlink_system_library,LIBSUITESPARSE,libcholmod_cuda))
$(eval $(call symlink_system_library,LIBSUITESPARSE,libcolamd))
$(eval $(call symlink_system_library,LIBSUITESPARSE,libumfpack))
$(eval $(call symlink_system_library,LIBSUITESPARSE,libspqr))
$(eval $(call symlink_system_library,LIBSUITESPARSE,libspqr_cuda))
$(eval $(call symlink_system_library,LIBSUITESPARSE,libsuitesparseconfig))
# EXCLUDED LIBRARIES (installed/used, but not vendored for use with dlopen):
# libunwind
Expand Down
17 changes: 9 additions & 8 deletions base/binaryplatforms.jl
Original file line number Diff line number Diff line change
Expand Up @@ -661,18 +661,12 @@ const libstdcxx_version_mapping = Dict{String,String}(
"libstdcxx" => "-libstdcxx\\d+",
)

"""
parse(::Type{Platform}, triplet::AbstractString)
Parses a string platform triplet back into a `Platform` object.
"""
function Base.parse(::Type{Platform}, triplet::String; validate_strict::Bool = false)
const triplet_regex = let
# Helper function to collapse dictionary of mappings down into a regex of
# named capture groups joined by "|" operators
c(mapping) = string("(",join(["(?<$k>$v)" for (k, v) in mapping], "|"), ")")

# We're going to build a mondo regex here to parse everything:
triplet_regex = Regex(string(
Regex(string(
"^",
# First, the core triplet; arch/os/libc/call_abi
c(arch_mapping),
Expand All @@ -687,7 +681,14 @@ function Base.parse(::Type{Platform}, triplet::String; validate_strict::Bool = f
"(?<tags>(?:-[^-]+\\+[^-]+)*)?",
"\$",
))
end

"""
parse(::Type{Platform}, triplet::AbstractString)
Parses a string platform triplet back into a `Platform` object.
"""
function Base.parse(::Type{Platform}, triplet::String; validate_strict::Bool = false)
m = match(triplet_regex, triplet)
if m !== nothing
# Helper function to find the single named field within the giant regex
Expand Down
89 changes: 37 additions & 52 deletions base/broadcast.jl
Original file line number Diff line number Diff line change
Expand Up @@ -571,15 +571,15 @@ an `Int`.
Any remaining indices in `I` beyond the length of the `keep` tuple are truncated. The `keep` and `default`
tuples may be created by `newindexer(argument)`.
"""
Base.@propagate_inbounds newindex(arg, I::CartesianIndex) = CartesianIndex(_newindex(axes(arg), I.I))
Base.@propagate_inbounds newindex(arg, I::Integer) = CartesianIndex(_newindex(axes(arg), (I,)))
Base.@propagate_inbounds newindex(arg, I::CartesianIndex) = to_index(_newindex(axes(arg), I.I))
Base.@propagate_inbounds newindex(arg, I::Integer) = to_index(_newindex(axes(arg), (I,)))
Base.@propagate_inbounds _newindex(ax::Tuple, I::Tuple) = (ifelse(length(ax[1]) == 1, ax[1][1], I[1]), _newindex(tail(ax), tail(I))...)
Base.@propagate_inbounds _newindex(ax::Tuple{}, I::Tuple) = ()
Base.@propagate_inbounds _newindex(ax::Tuple, I::Tuple{}) = (ax[1][1], _newindex(tail(ax), ())...)
Base.@propagate_inbounds _newindex(ax::Tuple{}, I::Tuple{}) = ()

# If dot-broadcasting were already defined, this would be `ifelse.(keep, I, Idefault)`.
@inline newindex(I::CartesianIndex, keep, Idefault) = CartesianIndex(_newindex(I.I, keep, Idefault))
@inline newindex(I::CartesianIndex, keep, Idefault) = to_index(_newindex(I.I, keep, Idefault))
@inline newindex(i::Integer, keep::Tuple, idefault) = ifelse(keep[1], i, idefault[1])
@inline newindex(i::Integer, keep::Tuple{}, idefault) = CartesianIndex(())
@inline _newindex(I, keep, Idefault) =
Expand All @@ -599,18 +599,14 @@ Base.@propagate_inbounds _newindex(ax::Tuple{}, I::Tuple{}) = ()
(Base.length(ind1)::Integer != 1, keep...), (first(ind1), Idefault...)
end

@inline function Base.getindex(bc::Broadcasted, I::Union{Integer,CartesianIndex})
@inline function Base.getindex(bc::Broadcasted, Is::Vararg{Union{Integer,CartesianIndex},N}) where {N}
I = to_index(Base.IteratorsMD.flatten(Is))
@boundscheck checkbounds(bc, I)
@inbounds _broadcast_getindex(bc, I)
end
Base.@propagate_inbounds Base.getindex(
bc::Broadcasted,
i1::Union{Integer,CartesianIndex},
i2::Union{Integer,CartesianIndex},
I::Union{Integer,CartesianIndex}...,
) =
bc[CartesianIndex((i1, i2, I...))]
Base.@propagate_inbounds Base.getindex(bc::Broadcasted) = bc[CartesianIndex(())]
to_index(::Tuple{}) = CartesianIndex()
to_index(Is::Tuple{Any}) = Is[1]
to_index(Is::Tuple) = CartesianIndex(Is)

@inline Base.checkbounds(bc::Broadcasted, I::Union{Integer,CartesianIndex}) =
Base.checkbounds_indices(Bool, axes(bc), (I,)) || Base.throw_boundserror(bc, (I,))
Expand Down Expand Up @@ -974,53 +970,42 @@ preprocess(dest, x) = extrude(broadcast_unalias(dest, x))
return dest
end

# Performance optimization: for BitVector outputs, we cache the result
# in a 64-bit register before writing into memory (to bypass LSQ)
@inline function copyto!(dest::BitVector, bc::Broadcasted{Nothing})
axes(dest) == axes(bc) || throwdm(axes(dest), axes(bc))
ischunkedbroadcast(dest, bc) && return chunkedcopyto!(dest, bc)
destc = dest.chunks
bcp = preprocess(dest, bc)
length(bcp) <= 0 && return dest
len = Base.num_bit_chunks(Int(length(bcp)))
@inbounds for i = 0:(len - 2)
z = UInt64(0)
for j = 0:63
z |= UInt64(bcp[i*64 + j + 1]::Bool) << (j & 63)
end
destc[i + 1] = z
end
@inbounds let i = len - 1
z = UInt64(0)
for j = 0:((length(bcp) - 1) & 63)
z |= UInt64(bcp[i*64 + j + 1]::Bool) << (j & 63)
end
destc[i + 1] = z
end
return dest
end

# Performance optimization: for BitArray outputs, we cache the result
# in a "small" Vector{Bool}, and then copy in chunks into the output
# in a 64-bit register before writing into memory (to bypass LSQ)
@inline function copyto!(dest::BitArray, bc::Broadcasted{Nothing})
axes(dest) == axes(bc) || throwdm(axes(dest), axes(bc))
ischunkedbroadcast(dest, bc) && return chunkedcopyto!(dest, bc)
length(dest) < 256 && return invoke(copyto!, Tuple{AbstractArray, Broadcasted{Nothing}}, dest, bc)
tmp = Vector{Bool}(undef, bitcache_size)
destc = dest.chunks
cind = 1
ndims(dest) == 0 && (dest[] = bc[]; return dest)
bc′ = preprocess(dest, bc)
@inbounds for P in Iterators.partition(eachindex(bc′), bitcache_size)
ind = 1
@simd for I in P
tmp[ind] = bc′[I]
ind += 1
ax = axes(bc′)
ax1, out = ax[1], CartesianIndices(tail(ax))
destc, indc = dest.chunks, 0
bitst, remain = 0, UInt64(0)
for I in out
i = first(ax1) - 1
if ndims(bc) == 1 || bitst >= 64 - length(ax1)
if ndims(bc) > 1 && bitst != 0
@inbounds @simd for j = bitst:63
remain |= UInt64(convert(Bool, bc′[i+=1, I])) << (j & 63)
end
@inbounds destc[indc+=1] = remain
bitst, remain = 0, UInt64(0)
end
while i <= last(ax1) - 64
z = UInt64(0)
@inbounds @simd for j = 0:63
z |= UInt64(convert(Bool, bc′[i+=1, I])) << (j & 63)
end
@inbounds destc[indc+=1] = z
end
end
@simd for i in ind:bitcache_size
tmp[i] = false
@inbounds @simd for j = i+1:last(ax1)
remain |= UInt64(convert(Bool, bc′[j, I])) << (bitst & 63)
bitst += 1
end
dumpbitcache(destc, cind, tmp)
cind += bitcache_chunks
end
@inbounds if bitst != 0
destc[indc+=1] = remain
end
return dest
end
Expand Down
32 changes: 20 additions & 12 deletions base/compiler/abstractinterpretation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2119,8 +2119,14 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f),
abstract_call_gf_by_type(interp, f, ArgInfo(nothing, T), si, atype, sv, max_methods)
end
pT = typevar_tfunc(𝕃ᵢ, n, lb_var, ub_var)
effects = builtin_effects(𝕃ᵢ, Core._typevar, Any[n, lb_var, ub_var], pT)
return CallMeta(pT, Any, effects, call.info)
typevar_argtypes = Any[n, lb_var, ub_var]
effects = builtin_effects(𝕃ᵢ, Core._typevar, typevar_argtypes, pT)
if effects.nothrow
exct = Union{}
else
exct = builtin_exct(𝕃ᵢ, Core._typevar, typevar_argtypes, pT)
end
return CallMeta(pT, exct, effects, call.info)
elseif f === UnionAll
call = abstract_call_gf_by_type(interp, f, ArgInfo(nothing, Any[Const(UnionAll), Any, Any]), si, Tuple{Type{UnionAll}, Any, Any}, sv, max_methods)
return abstract_call_unionall(interp, argtypes, call)
Expand Down Expand Up @@ -2310,11 +2316,7 @@ function abstract_eval_cfunction(interp::AbstractInterpreter, e::Expr, vtypes::U
end

function abstract_eval_special_value(interp::AbstractInterpreter, @nospecialize(e), vtypes::Union{VarTable,Nothing}, sv::AbsIntState)
if isa(e, QuoteNode)
effects = Effects(EFFECTS_TOTAL;
inaccessiblememonly = is_mutation_free_argtype(typeof(e.value)) ? ALWAYS_TRUE : ALWAYS_FALSE)
return RTEffects(Const(e.value), Union{}, effects)
elseif isa(e, SSAValue)
if isa(e, SSAValue)
return RTEffects(abstract_eval_ssavalue(e, sv), Union{}, EFFECTS_TOTAL)
elseif isa(e, SlotNumber)
if vtypes !== nothing
Expand All @@ -2335,8 +2337,12 @@ function abstract_eval_special_value(interp::AbstractInterpreter, @nospecialize(
elseif isa(e, GlobalRef)
return abstract_eval_globalref(interp, e, sv)
end

return RTEffects(Const(e), Union{}, EFFECTS_TOTAL)
if isa(e, QuoteNode)
e = e.value
end
effects = Effects(EFFECTS_TOTAL;
inaccessiblememonly = is_mutation_free_argtype(typeof(e)) ? ALWAYS_TRUE : ALWAYS_FALSE)
return RTEffects(Const(e), Union{}, effects)
end

function abstract_eval_value_expr(interp::AbstractInterpreter, e::Expr, sv::AbsIntState)
Expand Down Expand Up @@ -3288,10 +3294,12 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState)
# Process non control-flow statements
(; changes, rt, exct) = abstract_eval_basic_statement(interp,
stmt, currstate, frame)
if exct !== Union{}
update_exc_bestguess!(interp, exct, frame)
end
if !has_curr_ssaflag(frame, IR_FLAG_NOTHROW)
if exct !== Union{}
update_exc_bestguess!(interp, exct, frame)
# TODO: assert that these conditions match. For now, we assume the `nothrow` flag
# to be correct, but allow the exct to be an over-approximation.
end
propagate_to_error_handler!(currstate, frame, 𝕃ᵢ)
end
if rt === Bottom
Expand Down
9 changes: 6 additions & 3 deletions base/compiler/abstractlattice.jl
Original file line number Diff line number Diff line change
Expand Up @@ -285,9 +285,12 @@ has_extended_unionsplit(::AnyMustAliasesLattice) = true
has_extended_unionsplit(::JLTypeLattice) = false

# Curried versions
(lattice::AbstractLattice) = (@nospecialize(a), @nospecialize(b)) -> (lattice, a, b)
(lattice::AbstractLattice) = (@nospecialize(a), @nospecialize(b)) -> (lattice, a, b)
(lattice::AbstractLattice) = (@nospecialize(a), @nospecialize(b)) -> (lattice, a, b)
(𝕃::AbstractLattice) = (@nospecialize(a), @nospecialize(b)) -> (𝕃, a, b)
(𝕃::AbstractLattice) = (@nospecialize(a), @nospecialize(b)) -> (𝕃, a, b)
(𝕃::AbstractLattice) = (@nospecialize(a), @nospecialize(b)) -> (𝕃, a, b)
partialorder(𝕃::AbstractLattice) = (𝕃)
strictpartialorder(𝕃::AbstractLattice) = (𝕃)
strictneqpartialorder(𝕃::AbstractLattice) = (𝕃)

# Fallbacks for external packages using these methods
const fallback_lattice = InferenceLattice(BaseInferenceLattice.instance)
Expand Down
2 changes: 1 addition & 1 deletion base/compiler/ssair/EscapeAnalysis/EscapeAnalysis.jl
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const AInfo = IdSet{Any}
x::EscapeInfo
A lattice for escape information, which holds the following properties:
- `x.Analyzed::Bool`: not formally part of the lattice, only indicates `x` has not been analyzed or not
- `x.Analyzed::Bool`: not formally part of the lattice, only indicates whether `x` has been analyzed
- `x.ReturnEscape::Bool`: indicates `x` can escape to the caller via return
- `x.ThrownEscape::BitSet`: records SSA statement numbers where `x` can be thrown as exception:
* `isempty(x.ThrownEscape)`: `x` will never be thrown in this call frame (the bottom)
Expand Down
28 changes: 21 additions & 7 deletions base/compiler/ssair/ir.jl
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ block_for_inst(cfg::CFG, inst::Int) = block_for_inst(cfg.index, inst)
end
end
end
# and add add one more basic block start after the last statement
# and add one more basic block start after the last statement
for i = length(stmts):-1:1
if stmts[i] !== nothing
push!(jump_dests, i+1)
Expand Down Expand Up @@ -1117,7 +1117,7 @@ function find_ssavalue_uses1(compact::IncrementalCompact)
end

function _oracle_check(compact::IncrementalCompact)
(observed_used_ssas, observed_used_newssas) = Core.Compiler.find_ssavalue_uses1(compact)
(observed_used_ssas, observed_used_newssas) = find_ssavalue_uses1(compact)
for i = 1:length(observed_used_ssas)
if observed_used_ssas[i] != compact.used_ssas[i]
return (observed_used_ssas, observed_used_newssas, SSAValue(i))
Expand Down Expand Up @@ -1340,8 +1340,8 @@ function kill_edge!(compact::IncrementalCompact, active_bb::Int, from::Int, to::
else
stmts = compact.ir.cfg.blocks[to].stmts
for stmt in CompactPeekIterator(compact, first(stmts), last(stmts))
stmt === nothing && continue
isa(stmt, PhiNode) || break
is_valid_phiblock_stmt(stmt) || break
isa(stmt, PhiNode) || continue
i = findfirst(x::Int32->x==from, stmt.edges)
if i !== nothing
deleteat!(stmt.edges, i)
Expand Down Expand Up @@ -1684,13 +1684,27 @@ struct CompactPeekIterator
compact::IncrementalCompact
start_idx::Int
end_idx::Int
include_stmts_before_start::Bool
end
CompactPeekIterator(compact::IncrementalCompact, start_idx::Int, end_idx::Int) =
CompactPeekIterator(compact, start_idx, end_idx, false)


function CompactPeekIterator(compact::IncrementalCompact, start_idx::Int)
return CompactPeekIterator(compact, start_idx, 0)
end

entry_at_idx(entry::NewNodeInfo, idx::Int) = entry.attach_after ? entry.pos == idx - 1 : entry.pos == idx
function entry_at_idx(entry::NewNodeInfo, idx::Int, start_idx::Int, include_stmts_before_start::Bool)
if entry.attach_after
if !include_stmts_before_start
entry.pos >= start_idx || return false
end
return entry.pos == idx - 1
else
return entry.pos == idx
end
end

function iterate(it::CompactPeekIterator, (idx, aidx, bidx)::NTuple{3, Int}=(it.start_idx, it.compact.new_nodes_idx, 1))
if it.end_idx > 0 && idx > it.end_idx
return nothing
Expand All @@ -1702,15 +1716,15 @@ function iterate(it::CompactPeekIterator, (idx, aidx, bidx)::NTuple{3, Int}=(it.
if compact.new_nodes_idx <= length(compact.perm)
new_nodes = compact.ir.new_nodes
for eidx in aidx:length(compact.perm)
if entry_at_idx(new_nodes.info[compact.perm[eidx]], idx)
if entry_at_idx(new_nodes.info[compact.perm[eidx]], idx, it.start_idx, it.include_stmts_before_start)
entry = new_nodes.stmts[compact.perm[eidx]]
return (entry[:stmt], (idx, eidx+1, bidx))
end
end
end
if !isempty(compact.pending_perm)
for eidx in bidx:length(compact.pending_perm)
if entry_at_idx(compact.pending_nodes.info[compact.pending_perm[eidx]], idx)
if entry_at_idx(compact.pending_nodes.info[compact.pending_perm[eidx]], idx, it.start_idx, it.include_stmts_before_start)
entry = compact.pending_nodes.stmts[compact.pending_perm[eidx]]
return (entry[:stmt], (idx, aidx, eidx+1))
end
Expand Down
Loading

0 comments on commit 05c6909

Please sign in to comment.