diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000000000..2ad7fdc1efa0a --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" + open-pull-requests-limit: 100 + labels: + - "dependencies" + - "github-actions" + - "domain:ci" diff --git a/.github/workflows/LabelCheck.yml b/.github/workflows/LabelCheck.yml index 0ff56f4b9dfdc..c966e478e3fe0 100644 --- a/.github/workflows/LabelCheck.yml +++ b/.github/workflows/LabelCheck.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 2 steps: - - uses: yogevbd/enforce-label-action@2.2.2 + - uses: yogevbd/enforce-label-action@a3c219da6b8fa73f6ba62b68ff09c469b3a1c024 # 2.2.2 with: # REQUIRED_LABELS_ANY: "bug,enhancement,skip-changelog" # REQUIRED_LABELS_ANY_DESCRIPTION: "Select at least one label ['bug','enhancement','skip-changelog']" diff --git a/.github/workflows/Typos.yml b/.github/workflows/Typos.yml index da5a6a550abe8..6c9eeacc21800 100644 --- a/.github/workflows/Typos.yml +++ b/.github/workflows/Typos.yml @@ -11,11 +11,11 @@ jobs: timeout-minutes: 5 steps: - name: Checkout the JuliaLang/julia repository - uses: actions/checkout@v4 + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 with: persist-credentials: false - name: Check spelling with typos - #uses: crate-ci/typos@master + #uses: crate-ci/typos@c7af4712eda24dd1ef54bd8212973888489eb0ce # v1.23.5 env: GH_TOKEN: "${{ github.token }}" run: | diff --git a/.github/workflows/Whitespace.yml b/.github/workflows/Whitespace.yml new file mode 100644 index 0000000000000..5706f6148dc33 --- /dev/null +++ b/.github/workflows/Whitespace.yml @@ -0,0 +1,23 @@ +name: Whitespace + +permissions: {} + +on: + push: + branches: + - master + pull_request: + +jobs: + whitespace: + name: Check whitespace + runs-on: ubuntu-latest + timeout-minutes: 2 + steps: + - name: Checkout the JuliaLang/julia repository + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + with: + persist-credentials: false + - name: Check whitespace + run: | + contrib/check-whitespace.jl diff --git a/.github/workflows/cffconvert.yml b/.github/workflows/cffconvert.yml index 751476865ae4c..4c9debb246f3f 100644 --- a/.github/workflows/cffconvert.yml +++ b/.github/workflows/cffconvert.yml @@ -23,11 +23,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out a copy of the repository - uses: actions/checkout@v4 + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 with: persist-credentials: false - name: Check whether the citation metadata from CITATION.cff is valid - uses: citation-file-format/cffconvert-github-action@2.0.0 + uses: citation-file-format/cffconvert-github-action@4cf11baa70a673bfdf9dad0acc7ee33b3f4b6084 # 2.0.0 with: args: "--validate" diff --git a/HISTORY.md b/HISTORY.md index 66f856143711c..7fb01c7e9a0e9 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -79,6 +79,8 @@ Multi-threading changes Build system changes -------------------- +* There is a new `Makefile` to build Julia and LLVM using the profile-guided and link-time optimizations (PGO and LTO) strategies, see `contrib/pgo-lto/Makefile` ([#45641]). + New library functions --------------------- @@ -414,6 +416,7 @@ Deprecated or removed [#44247]: https://github.com/JuliaLang/julia/issues/44247 [#45164]: https://github.com/JuliaLang/julia/issues/45164 [#45396]: https://github.com/JuliaLang/julia/issues/45396 +[#45641]: https://github.com/JuliaLang/julia/issues/45641 [#45962]: https://github.com/JuliaLang/julia/issues/45962 [#46196]: https://github.com/JuliaLang/julia/issues/46196 [#46372]: https://github.com/JuliaLang/julia/issues/46372 diff --git a/Makefile b/Makefile index 023c01aadaa2a..3d8bf5436b476 100644 --- a/Makefile +++ b/Makefile @@ -403,6 +403,10 @@ endif # Install appdata file mkdir -p $(DESTDIR)$(datarootdir)/metainfo/ $(INSTALL_F) $(JULIAHOME)/contrib/julia.appdata.xml $(DESTDIR)$(datarootdir)/metainfo/ + # Install terminal info database +ifneq ($(WITH_TERMINFO),0) + cp -R -L $(build_datarootdir)/terminfo $(DESTDIR)$(datarootdir) +endif # Update RPATH entries and JL_SYSTEM_IMAGE_PATH if $(private_libdir_rel) != $(build_private_libdir_rel) ifneq ($(private_libdir_rel),$(build_private_libdir_rel)) diff --git a/NEWS.md b/NEWS.md index c98fa6b862b67..4bbe7645165dd 100644 --- a/NEWS.md +++ b/NEWS.md @@ -63,6 +63,8 @@ Multi-threading changes Build system changes -------------------- +* There are new `Makefile`s to build Julia and LLVM using the Binary Optimization and Layout Tool (BOLT), see `contrib/bolt` and `contrib/pgo-lto-bolt` ([#54107]). + New library functions --------------------- @@ -70,6 +72,8 @@ New library functions * The new `isfull(c::Channel)` function can be used to check if `put!(c, some_value)` will block. ([#53159]) * `waitany(tasks; throw=false)` and `waitall(tasks; failfast=false, throw=false)` which wait multiple tasks at once ([#53341]). * `uuid7()` creates an RFC 9652 compliant UUID with version 7 ([#54834]). +* `insertdims(array; dims)` allows to insert singleton dimensions into an array which is the inverse operation to `dropdims` +* The new `Fix` type is a generalization of `Fix1/Fix2` for fixing a single argument ([#54653]). New library features -------------------- @@ -90,11 +94,15 @@ New library features data-races. Or use the callback form of `open` to have all that handled automatically. * `@timed` now additionally returns the elapsed compilation and recompilation time ([#52889]) +* `escape_string` takes additional keyword arguments `ascii=true` (to escape all + non-ASCII characters) and `fullhex=true` (to require full 4/8-digit hex numbers + for u/U escapes, e.g. for C compatibility) [#55099]). * `filter` can now act on a `NamedTuple` ([#50795]). * `tempname` can now take a suffix string to allow the file name to include a suffix and include that suffix in the uniquing checking ([#53474]) * `RegexMatch` objects can now be used to construct `NamedTuple`s and `Dict`s ([#50988]) * `Lockable` is now exported ([#54595]) +* New `ltruncate`, `rtruncate` and `ctruncate` functions for truncating strings to text width, accounting for char widths ([#55351]) Standard library changes ------------------------ @@ -163,6 +171,10 @@ Deprecated or removed External dependencies --------------------- +- The terminal info database, `terminfo`, is now vendored by default, providing a better + REPL user experience when `terminfo` is not available on the system. Julia can be built + without vendoring the database using the Makefile option `WITH_TERMINFO=0`. ([#55411]) + Tooling Improvements -------------------- diff --git a/base/Base.jl b/base/Base.jl index a47a3a5c6459d..221ab90d8d2a9 100644 --- a/base/Base.jl +++ b/base/Base.jl @@ -53,6 +53,9 @@ function setproperty!(x, f::Symbol, v) return setfield!(x, f, val) end +typeof(function getproperty end).name.constprop_heuristic = Core.FORCE_CONST_PROP +typeof(function setproperty! end).name.constprop_heuristic = Core.FORCE_CONST_PROP + dotgetproperty(x, f) = getproperty(x, f) getproperty(x::Module, f::Symbol, order::Symbol) = (@inline; getglobal(x, f, order)) diff --git a/base/abstractarray.jl b/base/abstractarray.jl index 8d60a2443ba47..3f8886e14940c 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -1264,6 +1264,10 @@ function _memory_offset(x::AbstractArray, I::Vararg{Any,N}) where {N} return sum(map((i, s, o)->s*(i-o), J, strides(x), Tuple(first(CartesianIndices(x)))))*elsize(x) end +## Special constprop heuristics for getindex/setindex +typename(typeof(function getindex end)).constprop_heuristic = Core.ARRAY_INDEX_HEURISTIC +typename(typeof(function setindex! end)).constprop_heuristic = Core.ARRAY_INDEX_HEURISTIC + ## Approach: # We only define one fallback method on getindex for all argument types. # That dispatches to an (inlined) internal _getindex function, where the goal is @@ -1917,7 +1921,7 @@ julia> vcat(range(1, 2, length=3)) # collects lazy ranges 2.0 julia> two = ([10, 20, 30]', Float64[4 5 6; 7 8 9]) # row vector and a matrix -([10 20 30], [4.0 5.0 6.0; 7.0 8.0 9.0]) +(adjoint([10, 20, 30]), [4.0 5.0 6.0; 7.0 8.0 9.0]) julia> vcat(two...) 3×3 Matrix{Float64}: @@ -3404,6 +3408,8 @@ mapany(f, itr) = Any[f(x) for x in itr] Transform collection `c` by applying `f` to each element. For multiple collection arguments, apply `f` elementwise, and stop when any of them is exhausted. +The element type of the result is determined in the same manner as in [`collect`](@ref). + See also [`map!`](@ref), [`foreach`](@ref), [`mapreduce`](@ref), [`mapslices`](@ref), [`zip`](@ref), [`Iterators.map`](@ref). # Examples @@ -3519,6 +3525,35 @@ julia> map(+, [1 2; 3 4], [1,10,100,1000], zeros(3,1)) # iterates until 3rd is """ map(f, it, iters...) = collect(Generator(f, it, iters...)) +# Generic versions of push! for AbstractVector +# These are specialized further for Vector for faster resizing and setindexing +function push!(a::AbstractVector{T}, item) where T + # convert first so we don't grow the array if the assignment won't work + itemT = item isa T ? item : convert(T, item)::T + new_length = length(a) + 1 + resize!(a, new_length) + a[new_length] = itemT + return a +end + +# specialize and optimize the single argument case +function push!(a::AbstractVector{Any}, @nospecialize x) + new_length = length(a) + 1 + resize!(a, new_length) + a[new_length] = x + return a +end +function push!(a::AbstractVector{Any}, @nospecialize x...) + @_terminates_locally_meta + na = length(a) + nx = length(x) + resize!(a, na + nx) + for i = 1:nx + a[na+i] = x[i] + end + return a +end + # multi-item push!, pushfirst! (built on top of type-specific 1-item version) # (note: must not cause a dispatch loop when 1-item case is not defined) push!(A, a, b) = push!(push!(A, a), b) @@ -3526,6 +3561,9 @@ push!(A, a, b, c...) = push!(push!(A, a, b), c...) pushfirst!(A, a, b) = pushfirst!(pushfirst!(A, b), a) pushfirst!(A, a, b, c...) = pushfirst!(pushfirst!(A, c...), a, b) +# sizehint! does not nothing by default +sizehint!(a::AbstractVector, _) = a + ## hashing AbstractArray ## const hash_abstractarray_seed = UInt === UInt64 ? 0x7e2d6fb6448beb77 : 0xd4514ce5 diff --git a/base/abstractarraymath.jl b/base/abstractarraymath.jl index a9efc2b87bee4..0f028a0f66729 100644 --- a/base/abstractarraymath.jl +++ b/base/abstractarraymath.jl @@ -93,6 +93,70 @@ function _dropdims(A::AbstractArray, dims::Dims) end _dropdims(A::AbstractArray, dim::Integer) = _dropdims(A, (Int(dim),)) + +""" + insertdims(A; dims) + +Inverse of [`dropdims`](@ref); return an array with new singleton dimensions +at every dimension in `dims`. + +Repeated dimensions are forbidden and the largest entry in `dims` must be +less than or equal than `ndims(A) + length(dims)`. + +The result shares the same underlying data as `A`, such that the +result is mutable if and only if `A` is mutable, and setting elements of one +alters the values of the other. + +See also: [`dropdims`](@ref), [`reshape`](@ref), [`vec`](@ref). +# Examples +```jldoctest +julia> x = [1 2 3; 4 5 6] +2×3 Matrix{Int64}: + 1 2 3 + 4 5 6 + +julia> insertdims(x, dims=3) +2×3×1 Array{Int64, 3}: +[:, :, 1] = + 1 2 3 + 4 5 6 + +julia> insertdims(x, dims=(1,2,5)) == reshape(x, 1, 1, 2, 3, 1) +true + +julia> dropdims(insertdims(x, dims=(1,2,5)), dims=(1,2,5)) +2×3 Matrix{Int64}: + 1 2 3 + 4 5 6 +``` + +!!! compat "Julia 1.12" + Requires Julia 1.12 or later. +""" +insertdims(A; dims) = _insertdims(A, dims) +function _insertdims(A::AbstractArray{T, N}, dims::NTuple{M, Int}) where {T, N, M} + for i in eachindex(dims) + 1 ≤ dims[i] || throw(ArgumentError("the smallest entry in dims must be ≥ 1.")) + dims[i] ≤ N+M || throw(ArgumentError("the largest entry in dims must be not larger than the dimension of the array and the length of dims added")) + for j = 1:i-1 + dims[j] == dims[i] && throw(ArgumentError("inserted dims must be unique")) + end + end + + # acc is a tuple, where the first entry is the final shape + # the second entry off acc is a counter for the axes of A + inds= Base._foldoneto((acc, i) -> + i ∈ dims + ? ((acc[1]..., Base.OneTo(1)), acc[2]) + : ((acc[1]..., axes(A, acc[2])), acc[2] + 1), + ((), 1), Val(N+M)) + new_shape = inds[1] + return reshape(A, new_shape) +end +_insertdims(A::AbstractArray, dim::Integer) = _insertdims(A, (Int(dim),)) + + + ## Unary operators ## """ diff --git a/base/array.jl b/base/array.jl index 32c543ff12638..648fedd5036e1 100644 --- a/base/array.jl +++ b/base/array.jl @@ -660,7 +660,7 @@ _array_for(::Type{T}, itr, isz) where {T} = _array_for(T, isz, _similar_shape(it """ - collect(collection) + collect(iterator) Return an `Array` of all items in a collection or iterator. For dictionaries, returns a `Vector` of `key=>value` [Pair](@ref Pair)s. If the argument is array-like or is an iterator @@ -671,6 +671,9 @@ Used by [comprehensions](@ref man-comprehensions) to turn a [generator expressio into an `Array`. Thus, *on generators*, the square-brackets notation may be used instead of calling `collect`, see second example. +The element type of the returned array is based on the types of the values collected. However, if the +iterator is empty then the element type of the returned (empty) array is determined by type inference. + # Examples Collect items from a `UnitRange{Int64}` collection: @@ -692,6 +695,21 @@ julia> collect(x^2 for x in 1:3) 4 9 ``` + +Collecting an empty iterator where the result type depends on type inference: + +```jldoctest +julia> [rand(Bool) ? 1 : missing for _ in []] +Union{Missing, Int64}[] +``` + +When the iterator is non-empty, the result type depends only on values: + +```julia-repl +julia> [rand(Bool) ? 1 : missing for _ in [""]] +1-element Vector{Int64}: + 1 +``` """ collect(itr) = _collect(1:1 #= Array =#, itr, IteratorEltype(itr), IteratorSize(itr)) @@ -3064,3 +3082,56 @@ intersect(r::AbstractRange, v::AbstractVector) = intersect(v, r) _getindex(v, i) end end + +""" + wrap(Array, m::Union{Memory{T}, MemoryRef{T}}, dims) + +Create an array of size `dims` using `m` as the underlying memory. This can be thought of as a safe version +of [`unsafe_wrap`](@ref) utilizing `Memory` or `MemoryRef` instead of raw pointers. +""" +function wrap end + +# validity checking for _wrap calls, separate from allocation of Array so that it can be more likely to inline into the caller +function _wrap(ref::MemoryRef{T}, dims::NTuple{N, Int}) where {T, N} + mem = ref.mem + mem_len = length(mem) + 1 - memoryrefoffset(ref) + len = Core.checked_dims(dims...) + @boundscheck mem_len >= len || invalid_wrap_err(mem_len, dims, len) + if N != 1 && !(ref === GenericMemoryRef(mem) && len === mem_len) + mem = ccall(:jl_genericmemory_slice, Memory{T}, (Any, Ptr{Cvoid}, Int), mem, ref.ptr_or_offset, len) + ref = memoryref(mem) + end + return ref +end + +@noinline invalid_wrap_err(len, dims, proddims) = throw(DimensionMismatch(LazyString( + "Attempted to wrap a MemoryRef of length ", len, " with an Array of size dims=", dims, + " which is invalid because prod(dims) = ", proddims, " > ", len, + " so that the array would have more elements than the underlying memory can store."))) + +@eval @propagate_inbounds function wrap(::Type{Array}, m::MemoryRef{T}, dims::NTuple{N, Integer}) where {T, N} + dims = convert(Dims, dims) + ref = _wrap(m, dims) + $(Expr(:new, :(Array{T, N}), :ref, :dims)) +end + +@eval @propagate_inbounds function wrap(::Type{Array}, m::Memory{T}, dims::NTuple{N, Integer}) where {T, N} + dims = convert(Dims, dims) + ref = _wrap(memoryref(m), dims) + $(Expr(:new, :(Array{T, N}), :ref, :dims)) +end +@eval @propagate_inbounds function wrap(::Type{Array}, m::MemoryRef{T}, l::Integer) where {T} + dims = (Int(l),) + ref = _wrap(m, dims) + $(Expr(:new, :(Array{T, 1}), :ref, :dims)) +end +@eval @propagate_inbounds function wrap(::Type{Array}, m::Memory{T}, l::Integer) where {T} + dims = (Int(l),) + ref = _wrap(memoryref(m), (l,)) + $(Expr(:new, :(Array{T, 1}), :ref, :dims)) +end +@eval @propagate_inbounds function wrap(::Type{Array}, m::Memory{T}) where {T} + ref = memoryref(m) + dims = (length(m),) + $(Expr(:new, :(Array{T, 1}), :ref, :dims)) +end diff --git a/base/asyncmap.jl b/base/asyncmap.jl index c81afbb7e9115..02e515d2e0c6c 100644 --- a/base/asyncmap.jl +++ b/base/asyncmap.jl @@ -9,6 +9,8 @@ Uses multiple concurrent tasks to map `f` over a collection (or multiple equal length collections). For multiple collection arguments, `f` is applied elementwise. +The output is guaranteed to be the same order as the elements of the collection(s) `c`. + `ntasks` specifies the number of tasks to run concurrently. Depending on the length of the collections, if `ntasks` is unspecified, up to 100 tasks will be used for concurrent mapping. diff --git a/base/boot.jl b/base/boot.jl index 1481928b319b7..608e273d4b514 100644 --- a/base/boot.jl +++ b/base/boot.jl @@ -284,7 +284,8 @@ macro _foldable_meta() #=:inaccessiblememonly=#true, #=:noub=#true, #=:noub_if_noinbounds=#false, - #=:consistent_overlay=#false)) + #=:consistent_overlay=#false, + #=:nortcall=#true)) end macro inline() Expr(:meta, :inline) end @@ -1012,6 +1013,35 @@ const check_top_bit = check_sign_bit EnterNode(old::EnterNode, new_dest::Int) = isdefined(old, :scope) ? EnterNode(new_dest, old.scope) : EnterNode(new_dest) +# typename(_).constprop_heuristic +const FORCE_CONST_PROP = 0x1 +const ARRAY_INDEX_HEURISTIC = 0x2 +const ITERATE_HEURISTIC = 0x3 +const SAMETYPE_HEURISTIC = 0x4 + +# `typename` has special tfunc support in inference to improve +# the result for `Type{Union{...}}`. It is defined here, so that the Compiler +# can look it up by value. +struct TypeNameError <: Exception + a + TypeNameError(@nospecialize(a)) = new(a) +end + +typename(a) = throw(TypeNameError(a)) +typename(a::DataType) = a.name +function typename(a::Union) + ta = typename(a.a) + tb = typename(a.b) + ta === tb || throw(TypeNameError(a)) + return tb +end +typename(union::UnionAll) = typename(union.body) + +# Special inference support to avoid execess specialization of these methods. +# TODO: Replace this by a generic heuristic. +(>:)(@nospecialize(a), @nospecialize(b)) = (b <: a) +(!==)(@nospecialize(a), @nospecialize(b)) = Intrinsics.not_int(a === b) + include(Core, "optimized_generics.jl") ccall(:jl_set_istopmod, Cvoid, (Any, Bool), Core, true) diff --git a/base/broadcast.jl b/base/broadcast.jl index 57eac7f3a094c..927c946e53e02 100644 --- a/base/broadcast.jl +++ b/base/broadcast.jl @@ -751,6 +751,7 @@ The resulting container type is established by the following rules: - All other combinations of arguments default to returning an `Array`, but custom container types can define their own implementation and promotion-like rules to customize the result when they appear as arguments. + - The element type is determined in the same manner as in [`collect`](@ref). A special syntax exists for broadcasting: `f.(args...)` is equivalent to `broadcast(f, args...)`, and nested `f.(g.(args...))` calls are fused into a diff --git a/base/client.jl b/base/client.jl index aa0739eaed0fe..3aebfaf6de696 100644 --- a/base/client.jl +++ b/base/client.jl @@ -339,11 +339,13 @@ function _global_julia_startup_file() # If it is not found, then continue on to the relative path based on Sys.BINDIR BINDIR = Sys.BINDIR SYSCONFDIR = Base.SYSCONFDIR + p1 = nothing if !isempty(SYSCONFDIR) p1 = abspath(BINDIR, SYSCONFDIR, "julia", "startup.jl") isfile(p1) && return p1 end p2 = abspath(BINDIR, "..", "etc", "julia", "startup.jl") + p1 == p2 && return nothing # don't check the same path twice isfile(p2) && return p2 return nothing end diff --git a/base/cmd.jl b/base/cmd.jl index 202527abdf644..84ec52f865e98 100644 --- a/base/cmd.jl +++ b/base/cmd.jl @@ -482,7 +482,7 @@ function cmd_gen(parsed) end end -@assume_effects :effect_free :terminates_globally :noub function cmd_gen( +@assume_effects :foldable !:consistent function cmd_gen( parsed::Tuple{Vararg{Tuple{Vararg{Union{String, SubString{String}}}}}} ) return @invoke cmd_gen(parsed::Any) diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index 88c3324668869..90d395600bbde 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -13,20 +13,36 @@ call_result_unused(sv::InferenceState, currpc::Int) = isexpr(sv.src.code[currpc], :call) && isempty(sv.ssavalue_uses[currpc]) call_result_unused(si::StmtInfo) = !si.used +is_const_bool_or_bottom(@nospecialize(b)) = (isa(b, Const) && isa(b.val, Bool)) || b == Bottom +function can_propagate_conditional(@nospecialize(rt), argtypes::Vector{Any}) + isa(rt, InterConditional) || return false + if rt.slot > length(argtypes) + # In the vararg tail - can't be conditional + @assert isvarargtype(argtypes[end]) + return false + end + return isa(argtypes[rt.slot], Conditional) && + is_const_bool_or_bottom(rt.thentype) && is_const_bool_or_bottom(rt.thentype) +end + +function propagate_conditional(rt::InterConditional, cond::Conditional) + new_thentype = rt.thentype === Const(false) ? cond.elsetype : cond.thentype + new_elsetype = rt.elsetype === Const(true) ? cond.thentype : cond.elsetype + if rt.thentype == Bottom + @assert rt.elsetype != Bottom + return Conditional(cond.slot, Bottom, new_elsetype) + elseif rt.elsetype == Bottom + @assert rt.thentype != Bottom + return Conditional(cond.slot, new_thentype, Bottom) + end + return Conditional(cond.slot, new_thentype, new_elsetype) +end + 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) - ⊑ₚ = ⊑(𝕃ₚ) - if !should_infer_this_call(interp, sv) - add_remark!(interp, sv, "Skipped call in throw block") - # At this point we are guaranteed to end up throwing on this path, - # which is all that's required for :consistent-cy. Of course, we don't - # know anything else about this statement. - effects = Effects(; consistent=ALWAYS_TRUE) - return CallMeta(Any, Any, effects, NoCallInfo()) - end - + ⊑ₚ, ⊔ₚ, ⊔ᵢ = partialorder(𝕃ₚ), join(𝕃ₚ), join(𝕃ᵢ) argtypes = arginfo.argtypes matches = find_method_matches(interp, argtypes, atype; max_methods) if isa(matches, FailedMethodMatch) @@ -37,7 +53,7 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f), (; valid_worlds, applicable, info) = matches update_valid_age!(sv, valid_worlds) napplicable = length(applicable) - rettype = excttype = Bottom + rettype = exctype = Bottom edges = MethodInstance[] conditionals = nothing # keeps refinement information of call argument types when the return type is boolean seen = 0 # number of signatures actually inferred @@ -96,8 +112,8 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f), const_results[i] = const_result end edge === nothing || push!(edges, edge) - this_rt = tmerge(this_rt, rt) - this_exct = tmerge(this_exct, exct) + this_rt = this_rt ⊔ₚ rt + this_exct = this_exct ⊔ₚ exct if bail_out_call(interp, this_rt, sv) break end @@ -156,8 +172,17 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f), end @assert !(this_conditional isa Conditional || this_rt isa MustAlias) "invalid lattice element returned from inter-procedural context" seen += 1 - rettype = tmerge(𝕃ₚ, rettype, this_rt) - excttype = tmerge(𝕃ₚ, excttype, this_exct) + + if can_propagate_conditional(this_conditional, argtypes) + # The only case where we need to keep this in rt is where + # we can directly propagate the conditional to a slot argument + # that is not one of our arguments, otherwise we keep all the + # relevant information in `conditionals` below. + this_rt = this_conditional + end + + rettype = rettype ⊔ₚ this_rt + exctype = exctype ⊔ₚ this_exct if has_conditional(𝕃ₚ, sv) && this_conditional !== Bottom && is_lattice_bool(𝕃ₚ, rettype) && fargs !== nothing if conditionals === nothing conditionals = Any[Bottom for _ in 1:length(argtypes)], @@ -165,8 +190,8 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f), end for i = 1:length(argtypes) cnd = conditional_argtype(𝕃ᵢ, this_conditional, sig, argtypes, i) - conditionals[1][i] = tmerge(𝕃ᵢ, conditionals[1][i], cnd.thentype) - conditionals[2][i] = tmerge(𝕃ᵢ, conditionals[2][i], cnd.elsetype) + conditionals[1][i] = conditionals[1][i] ⊔ᵢ cnd.thentype + conditionals[2][i] = conditionals[2][i] ⊔ᵢ cnd.elsetype end end if bail_out_call(interp, InferenceLoopState(sig, rettype, all_effects), sv) @@ -182,14 +207,14 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f), if seen ≠ napplicable # there is unanalyzed candidate, widen type and effects to the top - rettype = excttype = Any + rettype = exctype = Any all_effects = Effects() else if (matches isa MethodMatches ? (!matches.fullmatch || any_ambig(matches)) : (!all(matches.fullmatches) || any_ambig(matches))) # Account for the fact that we may encounter a MethodError with a non-covered or ambiguous signature. all_effects = Effects(all_effects; nothrow=false) - excttype = tmerge(𝕃ₚ, excttype, MethodError) + exctype = exctype ⊔ₚ MethodError end if sv isa InferenceState && fargs !== nothing slotrefinements = collect_slot_refinements(𝕃ᵢ, applicable, argtypes, fargs, sv) @@ -240,7 +265,7 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f), end end - return CallMeta(rettype, excttype, all_effects, info, slotrefinements) + return CallMeta(rettype, exctype, all_effects, info, slotrefinements) end struct FailedMethodMatch @@ -367,7 +392,7 @@ function from_interprocedural!(interp::AbstractInterpreter, @nospecialize(rt), s arginfo::ArgInfo, @nospecialize(maybecondinfo)) rt = collect_limitations!(rt, sv) if isa(rt, InterMustAlias) - rt = from_intermustalias(rt, arginfo, sv) + rt = from_intermustalias(typeinf_lattice(interp), rt, arginfo, sv) elseif is_lattice_bool(ipo_lattice(interp), rt) if maybecondinfo === nothing rt = widenconditional(rt) @@ -387,12 +412,13 @@ function collect_limitations!(@nospecialize(typ), sv::InferenceState) return typ end -function from_intermustalias(rt::InterMustAlias, arginfo::ArgInfo, sv::AbsIntState) +function from_intermustalias(𝕃ᵢ::AbstractLattice, rt::InterMustAlias, arginfo::ArgInfo, sv::AbsIntState) fargs = arginfo.fargs if fargs !== nothing && 1 ≤ rt.slot ≤ length(fargs) arg = ssa_def_slot(fargs[rt.slot], sv) if isa(arg, SlotNumber) argtyp = widenslotwrapper(arginfo.argtypes[rt.slot]) + ⊑ = partialorder(𝕃ᵢ) if rt.vartyp ⊑ argtyp return MustAlias(arg, rt.vartyp, rt.fldidx, rt.fldtyp) else @@ -408,10 +434,14 @@ function from_interconditional(𝕃ᵢ::AbstractLattice, @nospecialize(rt), sv:: has_conditional(𝕃ᵢ, sv) || return widenconditional(rt) (; fargs, argtypes) = arginfo fargs === nothing && return widenconditional(rt) + if can_propagate_conditional(rt, argtypes) + return propagate_conditional(rt, argtypes[rt.slot]::Conditional) + end slot = 0 alias = nothing thentype = elsetype = Any condval = maybe_extract_const_bool(rt) + ⊑, ⋤, ⊓ = partialorder(𝕃ᵢ), strictneqpartialorder(𝕃ᵢ), meet(𝕃ᵢ) for i in 1:length(fargs) # find the first argument which supports refinement, # and intersect all equivalent arguments with it @@ -447,24 +477,24 @@ function from_interconditional(𝕃ᵢ::AbstractLattice, @nospecialize(rt), sv:: end if condval === false thentype = Bottom - elseif ⊑(𝕃ᵢ, new_thentype, thentype) + elseif new_thentype ⊑ thentype thentype = new_thentype else - thentype = tmeet(𝕃ᵢ, thentype, widenconst(new_thentype)) + thentype = thentype ⊓ widenconst(new_thentype) end if condval === true elsetype = Bottom - elseif ⊑(𝕃ᵢ, new_elsetype, elsetype) + elseif new_elsetype ⊑ elsetype elsetype = new_elsetype else - elsetype = tmeet(𝕃ᵢ, elsetype, widenconst(new_elsetype)) + elsetype = elsetype ⊓ widenconst(new_elsetype) end - if (slot > 0 || condval !== false) && ⋤(𝕃ᵢ, thentype, old) + if (slot > 0 || condval !== false) && thentype ⋤ old slot = id if !(arg isa SlotNumber) && argtyp isa MustAlias alias = argtyp end - elseif (slot > 0 || condval !== true) && ⋤(𝕃ᵢ, elsetype, old) + elseif (slot > 0 || condval !== true) && elsetype ⋤ old slot = id if !(arg isa SlotNumber) && argtyp isa MustAlias alias = argtyp @@ -659,13 +689,23 @@ function abstract_call_method(interp::AbstractInterpreter, end add_remark!(interp, sv, washardlimit ? RECURSION_MSG_HARDLIMIT : RECURSION_MSG) # TODO (#48913) implement a proper recursion handling for irinterp: - # This works just because currently the `:terminate` condition guarantees that - # irinterp doesn't fail into unresolved cycles, but it's not a good solution. + # This works just because currently the `:terminate` condition usually means this is unreachable here + # for irinterp because there are not unresolved cycles, but it's not a good solution. # We should revisit this once we have a better story for handling cycles in irinterp. - if isa(topmost, InferenceState) + if isa(sv, InferenceState) + # since the hardlimit is against the edge to the parent frame, + # we should try to poison the whole edge, not just the topmost frame parentframe = frame_parent(topmost) - if isa(sv, InferenceState) && isa(parentframe, InferenceState) - poison_callstack!(sv, parentframe === nothing ? topmost : parentframe) + while !isa(parentframe, InferenceState) + # attempt to find a parent frame that can handle this LimitedAccuracy result correctly + # so we don't try to cache this incomplete intermediate result + parentframe === nothing && break + parentframe = frame_parent(parentframe) + end + if isa(parentframe, InferenceState) + poison_callstack!(sv, parentframe) + elseif isa(topmost, InferenceState) + poison_callstack!(sv, topmost) end end # n.b. this heuristic depends on the non-local state, so we must record the limit later @@ -940,7 +980,7 @@ function concrete_eval_eligible(interp::AbstractInterpreter, end end mi = result.edge - if mi !== nothing && is_foldable(effects) + if mi !== nothing && is_foldable(effects, #=check_rtcall=#true) if f !== nothing && is_all_const_arg(arginfo, #=start=#2) if (is_nonoverlayed(interp) || is_nonoverlayed(effects) || # Even if overlay methods are involved, when `:consistent_overlay` is @@ -1034,12 +1074,12 @@ function maybe_get_const_prop_profitable(interp::AbstractInterpreter, match::MethodMatch, sv::AbsIntState) method = match.method force = force_const_prop(interp, f, method) - if !const_prop_entry_heuristic(interp, result, si, sv, force) - # N.B. remarks are emitted within `const_prop_entry_heuristic` + if !const_prop_rettype_heuristic(interp, result, si, sv, force) + # N.B. remarks are emitted within `const_prop_rettype_heuristic` return nothing end if !const_prop_argument_heuristic(interp, arginfo, sv) - add_remark!(interp, sv, "[constprop] Disabled by argument and rettype heuristics") + add_remark!(interp, sv, "[constprop] Disabled by argument heuristics") return nothing end all_overridden = is_all_overridden(interp, arginfo, sv) @@ -1061,28 +1101,28 @@ function maybe_get_const_prop_profitable(interp::AbstractInterpreter, return mi end -function const_prop_entry_heuristic(interp::AbstractInterpreter, result::MethodCallResult, - si::StmtInfo, sv::AbsIntState, force::Bool) - if result.rt isa LimitedAccuracy +function const_prop_rettype_heuristic(interp::AbstractInterpreter, result::MethodCallResult, + si::StmtInfo, sv::AbsIntState, force::Bool) + rt = result.rt + if rt isa LimitedAccuracy # optimizations like inlining are disabled for limited frames, # thus there won't be much benefit in constant-prop' here # N.B. don't allow forced constprop' for safety (xref #52763) - add_remark!(interp, sv, "[constprop] Disabled by entry heuristic (limited accuracy)") + add_remark!(interp, sv, "[constprop] Disabled by rettype heuristic (limited accuracy)") return false elseif force return true elseif call_result_unused(si) && result.edgecycle - add_remark!(interp, sv, "[constprop] Disabled by entry heuristic (edgecycle with unused result)") + add_remark!(interp, sv, "[constprop] Disabled by rettype heuristic (edgecycle with unused result)") return false end # check if this return type is improvable (i.e. whether it's possible that with more # information, we might get a more precise type) - rt = result.rt if isa(rt, Type) # could always be improved to `Const`, `PartialStruct` or just a more precise type, # unless we're already at `Bottom` if rt === Bottom - add_remark!(interp, sv, "[constprop] Disabled by entry heuristic (erroneous result)") + add_remark!(interp, sv, "[constprop] Disabled by rettype heuristic (erroneous result)") return false end return true @@ -1091,14 +1131,15 @@ function const_prop_entry_heuristic(interp::AbstractInterpreter, result::MethodC return true elseif isa(rt, Const) if is_nothrow(result.effects) - add_remark!(interp, sv, "[constprop] Disabled by entry heuristic (nothrow const)") + add_remark!(interp, sv, "[constprop] Disabled by rettype heuristic (nothrow const)") return false end # Could still be improved to Bottom (or at least could see the effects improved) return true + else + add_remark!(interp, sv, "[constprop] Disabled by rettype heuristic (unimprovable result)") + return false end - add_remark!(interp, sv, "[constprop] Disabled by entry heuristic (unimprovable result)") - return false end # determines heuristically whether if constant propagation can be worthwhile @@ -1157,16 +1198,16 @@ end function force_const_prop(interp::AbstractInterpreter, @nospecialize(f), method::Method) return is_aggressive_constprop(method) || InferenceParams(interp).aggressive_constant_propagation || - istopfunction(f, :getproperty) || - istopfunction(f, :setproperty!) + typename(typeof(f)).constprop_heuristic === Core.FORCE_CONST_PROP end function const_prop_function_heuristic(interp::AbstractInterpreter, @nospecialize(f), arginfo::ArgInfo, all_overridden::Bool, sv::AbsIntState) argtypes = arginfo.argtypes + heuristic = typename(typeof(f)).constprop_heuristic if length(argtypes) > 1 𝕃ᵢ = typeinf_lattice(interp) - if istopfunction(f, :getindex) || istopfunction(f, :setindex!) + if heuristic === Core.ARRAY_INDEX_HEURISTIC arrty = argtypes[2] # don't propagate constant index into indexing of non-constant array if arrty isa Type && arrty <: AbstractArray && !issingletontype(arrty) @@ -1179,17 +1220,14 @@ function const_prop_function_heuristic(interp::AbstractInterpreter, @nospecializ elseif ⊑(𝕃ᵢ, arrty, Array) || ⊑(𝕃ᵢ, arrty, GenericMemory) return false end - elseif istopfunction(f, :iterate) + elseif heuristic === Core.ITERATE_HEURISTIC itrty = argtypes[2] if ⊑(𝕃ᵢ, itrty, Array) || ⊑(𝕃ᵢ, itrty, GenericMemory) return false end end end - if !all_overridden && (istopfunction(f, :+) || istopfunction(f, :-) || istopfunction(f, :*) || - istopfunction(f, :(==)) || istopfunction(f, :!=) || - istopfunction(f, :<=) || istopfunction(f, :>=) || istopfunction(f, :<) || istopfunction(f, :>) || - istopfunction(f, :<<) || istopfunction(f, :>>)) + if !all_overridden && heuristic === Core.SAMETYPE_HEURISTIC # it is almost useless to inline the op when all the same type, # but highly worthwhile to inline promote of a constant length(argtypes) > 2 || return false @@ -1370,7 +1408,6 @@ function matching_cache_argtypes(𝕃::AbstractLattice, mi::MethodInstance, given_argtypes = Vector{Any}(undef, length(argtypes)) def = mi.def::Method nargs = Int(def.nargs) - local condargs = nothing for i in 1:length(argtypes) argtype = argtypes[i] # forward `Conditional` if it conveys a constraint on any other argument @@ -1387,10 +1424,6 @@ function matching_cache_argtypes(𝕃::AbstractLattice, mi::MethodInstance, # TODO bail out here immediately rather than just propagating Bottom ? given_argtypes[i] = Bottom else - if condargs === nothing - condargs = Tuple{Int,Int}[] - end - push!(condargs, (slotid, i)) given_argtypes[i] = Conditional(slotid, thentype, elsetype) end continue @@ -2222,14 +2255,7 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f), end elseif is_return_type(f) return return_type_tfunc(interp, argtypes, si, sv) - elseif la == 2 && istopfunction(f, :!) - # handle Conditional propagation through !Bool - aty = argtypes[2] - if isa(aty, Conditional) - call = abstract_call_gf_by_type(interp, f, ArgInfo(fargs, Any[Const(f), Bool]), si, Tuple{typeof(f), Bool}, sv, max_methods) # make sure we've inferred `!(::Bool)` - return CallMeta(Conditional(aty.slot, aty.elsetype, aty.thentype), Any, call.effects, call.info) - end - elseif la == 3 && istopfunction(f, :!==) + elseif la == 3 && f === Core.:(!==) # mark !== as exactly a negated call to === call = abstract_call_gf_by_type(interp, f, ArgInfo(fargs, Any[Const(f), Any, Any]), si, Tuple{typeof(f), Any, Any}, sv, max_methods) rty = abstract_call_known(interp, (===), arginfo, si, sv, max_methods).rt @@ -2239,7 +2265,7 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f), return CallMeta(Const(rty.val === false), Bottom, EFFECTS_TOTAL, MethodResultPure()) end return call - elseif la == 3 && istopfunction(f, :(>:)) + elseif la == 3 && f === Core.:(>:) # mark issupertype as a exact alias for issubtype # swap T1 and T2 arguments and call <: if fargs !== nothing && length(fargs) == 3 @@ -2249,7 +2275,7 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f), end argtypes = Any[typeof(<:), argtypes[3], argtypes[2]] return abstract_call_known(interp, <:, ArgInfo(fargs, argtypes), si, sv, max_methods) - elseif la == 2 && istopfunction(f, :typename) + elseif la == 2 && f === Core.typename return CallMeta(typename_static(argtypes[2]), Bottom, EFFECTS_TOTAL, MethodResultPure()) elseif f === Core._hasmethod return _hasmethod_tfunc(interp, argtypes, sv) @@ -2884,8 +2910,9 @@ function override_effects(effects::Effects, override::EffectsOverride) notaskstate = override.notaskstate ? true : effects.notaskstate, inaccessiblememonly = override.inaccessiblememonly ? ALWAYS_TRUE : effects.inaccessiblememonly, noub = override.noub ? ALWAYS_TRUE : - (override.noub_if_noinbounds && effects.noub !== ALWAYS_TRUE) ? NOUB_IF_NOINBOUNDS : - effects.noub) + (override.noub_if_noinbounds && effects.noub !== ALWAYS_TRUE) ? NOUB_IF_NOINBOUNDS : + effects.noub, + nortcall = override.nortcall ? true : effects.nortcall) end isdefined_globalref(g::GlobalRef) = !iszero(ccall(:jl_globalref_boundp, Cint, (Any,), g)) @@ -3199,7 +3226,7 @@ function update_bestguess!(interp::AbstractInterpreter, frame::InferenceState, # narrow representation of bestguess slightly to prepare for tmerge with rt if rt isa InterConditional && bestguess isa Const slot_id = rt.slot - old_id_type = slottypes[slot_id] + old_id_type = widenconditional(slottypes[slot_id]) if bestguess.val === true && rt.elsetype !== Bottom bestguess = InterConditional(slot_id, old_id_type, Bottom) elseif bestguess.val === false && rt.thentype !== Bottom diff --git a/base/compiler/compiler.jl b/base/compiler/compiler.jl index 9aecdaad51aa5..5cc01391267d7 100644 --- a/base/compiler/compiler.jl +++ b/base/compiler/compiler.jl @@ -49,10 +49,11 @@ struct EffectsOverride noub::Bool noub_if_noinbounds::Bool consistent_overlay::Bool + nortcall::Bool end function EffectsOverride( override::EffectsOverride = - EffectsOverride(false, false, false, false, false, false, false, false, false, false); + EffectsOverride(false, false, false, false, false, false, false, false, false, false, false); consistent::Bool = override.consistent, effect_free::Bool = override.effect_free, nothrow::Bool = override.nothrow, @@ -62,7 +63,8 @@ function EffectsOverride( inaccessiblememonly::Bool = override.inaccessiblememonly, noub::Bool = override.noub, noub_if_noinbounds::Bool = override.noub_if_noinbounds, - consistent_overlay::Bool = override.consistent_overlay) + consistent_overlay::Bool = override.consistent_overlay, + nortcall::Bool = override.nortcall) return EffectsOverride( consistent, effect_free, @@ -73,9 +75,10 @@ function EffectsOverride( inaccessiblememonly, noub, noub_if_noinbounds, - consistent_overlay) + consistent_overlay, + nortcall) end -const NUM_EFFECTS_OVERRIDES = 10 # sync with julia.h +const NUM_EFFECTS_OVERRIDES = 11 # sync with julia.h # essential files and libraries include("essentials.jl") @@ -184,8 +187,7 @@ baremodule BuildSettings using Core: ARGS, include using Core.Compiler: >, getindex, length -MAX_METHODS::Int = 3 -UNOPTIMIZE_THROW_BLOCKS::Bool = true +global MAX_METHODS::Int = 3 if length(ARGS) > 2 && ARGS[2] === "--buildsettings" include(BuildSettings, ARGS[3]) diff --git a/base/compiler/effects.jl b/base/compiler/effects.jl index 0375b8dba922c..166df78f3130c 100644 --- a/base/compiler/effects.jl +++ b/base/compiler/effects.jl @@ -58,6 +58,9 @@ following meanings: methods are `:consistent` with their non-overlayed original counterparts (see [`Base.@assume_effects`](@ref) for the exact definition of `:consistenct`-cy). * `ALWAYS_FALSE`: this method may invoke overlayed methods. +- `nortcall::Bool`: this method does not call `Core.Compiler.return_type`, + and it is guaranteed that any other methods this method might call also do not call + `Core.Compiler.return_type`. Note that the representations above are just internal implementation details and thus likely to change in the future. See [`Base.@assume_effects`](@ref) for more detailed explanation @@ -103,6 +106,9 @@ The output represents the state of different effect properties in the following - `+o` (green): `ALWAYS_TRUE` - `-o` (red): `ALWAYS_FALSE` - `?o` (yellow): `CONSISTENT_OVERLAY` +9. `:nortcall` (`r`): + - `+r` (green): `true` + - `-r` (red): `false` """ struct Effects consistent::UInt8 @@ -113,6 +119,7 @@ struct Effects inaccessiblememonly::UInt8 noub::UInt8 nonoverlayed::UInt8 + nortcall::Bool function Effects( consistent::UInt8, effect_free::UInt8, @@ -121,7 +128,8 @@ struct Effects notaskstate::Bool, inaccessiblememonly::UInt8, noub::UInt8, - nonoverlayed::UInt8) + nonoverlayed::UInt8, + nortcall::Bool) return new( consistent, effect_free, @@ -130,7 +138,8 @@ struct Effects notaskstate, inaccessiblememonly, noub, - nonoverlayed) + nonoverlayed, + nortcall) end end @@ -160,10 +169,10 @@ const NOUB_IF_NOINBOUNDS = 0x01 << 1 # :nonoverlayed bits const CONSISTENT_OVERLAY = 0x01 << 1 -const EFFECTS_TOTAL = Effects(ALWAYS_TRUE, ALWAYS_TRUE, true, true, true, ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE) -const EFFECTS_THROWS = Effects(ALWAYS_TRUE, ALWAYS_TRUE, false, true, true, ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE) -const EFFECTS_UNKNOWN = Effects(ALWAYS_FALSE, ALWAYS_FALSE, false, false, false, ALWAYS_FALSE, ALWAYS_FALSE, ALWAYS_TRUE) # unknown mostly, but it's not overlayed at least (e.g. it's not a call) -const _EFFECTS_UNKNOWN = Effects(ALWAYS_FALSE, ALWAYS_FALSE, false, false, false, ALWAYS_FALSE, ALWAYS_FALSE, ALWAYS_FALSE) # unknown really +const EFFECTS_TOTAL = Effects(ALWAYS_TRUE, ALWAYS_TRUE, true, true, true, ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE, true) +const EFFECTS_THROWS = Effects(ALWAYS_TRUE, ALWAYS_TRUE, false, true, true, ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE, true) +const EFFECTS_UNKNOWN = Effects(ALWAYS_FALSE, ALWAYS_FALSE, false, false, false, ALWAYS_FALSE, ALWAYS_FALSE, ALWAYS_TRUE, false) # unknown mostly, but it's not overlayed at least (e.g. it's not a call) +const _EFFECTS_UNKNOWN = Effects(ALWAYS_FALSE, ALWAYS_FALSE, false, false, false, ALWAYS_FALSE, ALWAYS_FALSE, ALWAYS_FALSE, false) # unknown really function Effects(effects::Effects = _EFFECTS_UNKNOWN; consistent::UInt8 = effects.consistent, @@ -173,7 +182,8 @@ function Effects(effects::Effects = _EFFECTS_UNKNOWN; notaskstate::Bool = effects.notaskstate, inaccessiblememonly::UInt8 = effects.inaccessiblememonly, noub::UInt8 = effects.noub, - nonoverlayed::UInt8 = effects.nonoverlayed) + nonoverlayed::UInt8 = effects.nonoverlayed, + nortcall::Bool = effects.nortcall) return Effects( consistent, effect_free, @@ -182,7 +192,8 @@ function Effects(effects::Effects = _EFFECTS_UNKNOWN; notaskstate, inaccessiblememonly, noub, - nonoverlayed) + nonoverlayed, + nortcall) end function is_better_effects(new::Effects, old::Effects) @@ -247,6 +258,11 @@ function is_better_effects(new::Effects, old::Effects) elseif new.nonoverlayed != old.nonoverlayed return false end + if new.nortcall + any_improved |= !old.nortcall + elseif new.nortcall != old.nortcall + return false + end return any_improved end @@ -259,7 +275,8 @@ function merge_effects(old::Effects, new::Effects) merge_effectbits(old.notaskstate, new.notaskstate), merge_effectbits(old.inaccessiblememonly, new.inaccessiblememonly), merge_effectbits(old.noub, new.noub), - merge_effectbits(old.nonoverlayed, new.nonoverlayed)) + merge_effectbits(old.nonoverlayed, new.nonoverlayed), + merge_effectbits(old.nortcall, new.nortcall)) end function merge_effectbits(old::UInt8, new::UInt8) @@ -279,16 +296,18 @@ is_inaccessiblememonly(effects::Effects) = effects.inaccessiblememonly === ALWAY is_noub(effects::Effects) = effects.noub === ALWAYS_TRUE is_noub_if_noinbounds(effects::Effects) = effects.noub === NOUB_IF_NOINBOUNDS is_nonoverlayed(effects::Effects) = effects.nonoverlayed === ALWAYS_TRUE +is_nortcall(effects::Effects) = effects.nortcall # implies `is_notaskstate` & `is_inaccessiblememonly`, but not explicitly checked here -is_foldable(effects::Effects) = +is_foldable(effects::Effects, check_rtcall::Bool=false) = is_consistent(effects) && (is_noub(effects) || is_noub_if_noinbounds(effects)) && is_effect_free(effects) && - is_terminates(effects) + is_terminates(effects) && + (!check_rtcall || is_nortcall(effects)) -is_foldable_nothrow(effects::Effects) = - is_foldable(effects) && +is_foldable_nothrow(effects::Effects, check_rtcall::Bool=false) = + is_foldable(effects, check_rtcall) && is_nothrow(effects) # TODO add `is_noub` here? @@ -318,7 +337,8 @@ function encode_effects(e::Effects) ((e.notaskstate % UInt32) << 7) | ((e.inaccessiblememonly % UInt32) << 8) | ((e.noub % UInt32) << 10) | - ((e.nonoverlayed % UInt32) << 12) + ((e.nonoverlayed % UInt32) << 12) | + ((e.nortcall % UInt32) << 14) end function decode_effects(e::UInt32) @@ -330,7 +350,8 @@ function decode_effects(e::UInt32) _Bool((e >> 7) & 0x01), UInt8((e >> 8) & 0x03), UInt8((e >> 10) & 0x03), - UInt8((e >> 12) & 0x03)) + UInt8((e >> 12) & 0x03), + _Bool((e >> 14) & 0x01)) end function encode_effects_override(eo::EffectsOverride) @@ -345,6 +366,7 @@ function encode_effects_override(eo::EffectsOverride) eo.noub && (e |= (0x0001 << 7)) eo.noub_if_noinbounds && (e |= (0x0001 << 8)) eo.consistent_overlay && (e |= (0x0001 << 9)) + eo.nortcall && (e |= (0x0001 << 10)) return e end @@ -359,7 +381,8 @@ function decode_effects_override(e::UInt16) !iszero(e & (0x0001 << 6)), !iszero(e & (0x0001 << 7)), !iszero(e & (0x0001 << 8)), - !iszero(e & (0x0001 << 9))) + !iszero(e & (0x0001 << 9)), + !iszero(e & (0x0001 << 10))) end decode_statement_effects_override(ssaflag::UInt32) = diff --git a/base/compiler/inferencestate.jl b/base/compiler/inferencestate.jl index c358b1177251f..87647628f772e 100644 --- a/base/compiler/inferencestate.jl +++ b/base/compiler/inferencestate.jl @@ -312,6 +312,9 @@ mutable struct InferenceState nargtypes = length(argtypes) for i = 1:nslots argtyp = (i > nargtypes) ? Bottom : argtypes[i] + if argtyp === Bool && has_conditional(typeinf_lattice(interp)) + argtyp = Conditional(i, Const(true), Const(false)) + end slottypes[i] = argtyp bb_vartable1[i] = VarState(argtyp, i > nargtypes) end @@ -345,7 +348,6 @@ mutable struct InferenceState restrict_abstract_call_sites = isa(def, Module) # some more setups - InferenceParams(interp).unoptimize_throw_blocks && mark_throw_blocks!(src, handler_info) !iszero(cache_mode & CACHE_MODE_LOCAL) && push!(get_inference_cache(interp), result) this = new( @@ -515,72 +517,6 @@ function compute_trycatch(code::Vector{Any}, bbs::Union{Vector{BasicBlock},Nothi return handler_info end -function is_throw_call(e::Expr, code::Vector{Any}) - if e.head === :call - f = e.args[1] - if isa(f, SSAValue) - f = code[f.id] - end - if isa(f, GlobalRef) - ff = abstract_eval_globalref_type(f) - if isa(ff, Const) && ff.val === Core.throw - return true - end - end - end - return false -end - -function mark_throw_blocks!(src::CodeInfo, handler_info::Union{Nothing,HandlerInfo}) - for stmt in find_throw_blocks(src.code, handler_info) - src.ssaflags[stmt] |= IR_FLAG_THROW_BLOCK - end - return nothing -end - -# this utility function is incomplete and won't catch every block that always throws, since: -# - it only recognizes direct calls to `throw` within the target code, so it can't mark -# blocks that deterministically call `throw` internally, like those containing `error`. -# - it just does a reverse linear traverse of statements, there's a chance it might miss -# blocks, particularly when there are reverse control edges. -function find_throw_blocks(code::Vector{Any}, handler_info::Union{Nothing,HandlerInfo}) - stmts = BitSet() - n = length(code) - for i in n:-1:1 - s = code[i] - if isa(s, Expr) - if s.head === :gotoifnot - if i+1 in stmts && s.args[2]::Int in stmts - push!(stmts, i) - end - elseif s.head === :return - # see `ReturnNode` handling - elseif is_throw_call(s, code) - if handler_info === nothing || handler_info.handler_at[i][1] == 0 - push!(stmts, i) - end - elseif i+1 in stmts - push!(stmts, i) - end - elseif isa(s, ReturnNode) - # NOTE: it potentially makes sense to treat unreachable nodes - # (where !isdefined(s, :val)) as `throw` points, but that can cause - # worse codegen around the call site (issue #37558) - elseif isa(s, GotoNode) - if s.label in stmts - push!(stmts, i) - end - elseif isa(s, GotoIfNot) - if i+1 in stmts && s.dest in stmts - push!(stmts, i) - end - elseif i+1 in stmts - push!(stmts, i) - end - end - return stmts -end - # check if coverage mode is enabled function should_insert_coverage(mod::Module, debuginfo::DebugInfo) coverage_enabled(mod) && return true @@ -1099,30 +1035,6 @@ bail_out_apply(::AbstractInterpreter, state::InferenceLoopState, ::InferenceStat bail_out_apply(::AbstractInterpreter, state::InferenceLoopState, ::IRInterpretationState) = state.rt === Any -function should_infer_this_call(interp::AbstractInterpreter, sv::InferenceState) - if InferenceParams(interp).unoptimize_throw_blocks - # Disable inference of calls in throw blocks, since we're unlikely to - # need their types. There is one exception however: If up until now, the - # function has not seen any side effects, we would like to make sure there - # aren't any in the throw block either to enable other optimizations. - if is_stmt_throw_block(get_curr_ssaflag(sv)) - should_infer_for_effects(sv) || return false - end - end - return true -end -function should_infer_for_effects(sv::InferenceState) - def = sv.linfo.def - def isa Method || return false # toplevel frame will not be [semi-]concrete-evaluated - effects = sv.ipo_effects - override = decode_effects_override(def.purity) - effects.consistent === ALWAYS_FALSE && !is_effect_overridden(override, :consistent) && return false - effects.effect_free === ALWAYS_FALSE && !is_effect_overridden(override, :effect_free) && return false - !effects.terminates && !is_effect_overridden(override, :terminates_globally) && return false - return true -end -should_infer_this_call(::AbstractInterpreter, ::IRInterpretationState) = true - add_remark!(::AbstractInterpreter, ::InferenceState, remark) = return add_remark!(::AbstractInterpreter, ::IRInterpretationState, remark) = return diff --git a/base/compiler/optimize.jl b/base/compiler/optimize.jl index 85d4a92b3919a..936b604d373a0 100644 --- a/base/compiler/optimize.jl +++ b/base/compiler/optimize.jl @@ -23,34 +23,35 @@ const IR_FLAG_INBOUNDS = one(UInt32) << 0 const IR_FLAG_INLINE = one(UInt32) << 1 # This statement is marked as @noinline by user const IR_FLAG_NOINLINE = one(UInt32) << 2 -# This statement is on a code path that eventually `throw`s. -const IR_FLAG_THROW_BLOCK = one(UInt32) << 3 # An optimization pass has updated this statement in a way that may # have exposed information that inference did not see. Re-running # inference on this statement may be profitable. -const IR_FLAG_REFINED = one(UInt32) << 4 +const IR_FLAG_REFINED = one(UInt32) << 3 # This statement is proven :consistent -const IR_FLAG_CONSISTENT = one(UInt32) << 5 +const IR_FLAG_CONSISTENT = one(UInt32) << 4 # This statement is proven :effect_free -const IR_FLAG_EFFECT_FREE = one(UInt32) << 6 +const IR_FLAG_EFFECT_FREE = one(UInt32) << 5 # This statement is proven :nothrow -const IR_FLAG_NOTHROW = one(UInt32) << 7 +const IR_FLAG_NOTHROW = one(UInt32) << 6 # This statement is proven :terminates -const IR_FLAG_TERMINATES = one(UInt32) << 8 +const IR_FLAG_TERMINATES = one(UInt32) << 7 # This statement is proven :noub -const IR_FLAG_NOUB = one(UInt32) << 9 +const IR_FLAG_NOUB = one(UInt32) << 8 # TODO: Both of these should eventually go away once # This statement is :effect_free == EFFECT_FREE_IF_INACCESSIBLEMEMONLY -const IR_FLAG_EFIIMO = one(UInt32) << 10 +const IR_FLAG_EFIIMO = one(UInt32) << 9 # This statement is :inaccessiblememonly == INACCESSIBLEMEM_OR_ARGMEMONLY -const IR_FLAG_INACCESSIBLEMEM_OR_ARGMEM = one(UInt32) << 11 +const IR_FLAG_INACCESSIBLEMEM_OR_ARGMEM = one(UInt32) << 10 +# This statement is :nortcall +const IR_FLAG_NORTCALL = one(UInt32) << 11 # This statement has no users and may be deleted if flags get refined to IR_FLAGS_REMOVABLE const IR_FLAG_UNUSED = one(UInt32) << 12 const NUM_IR_FLAGS = 13 # sync with julia.h const IR_FLAGS_EFFECTS = - IR_FLAG_CONSISTENT | IR_FLAG_EFFECT_FREE | IR_FLAG_NOTHROW | IR_FLAG_TERMINATES | IR_FLAG_NOUB + IR_FLAG_CONSISTENT | IR_FLAG_EFFECT_FREE | IR_FLAG_NOTHROW | + IR_FLAG_TERMINATES | IR_FLAG_NOUB | IR_FLAG_NORTCALL const IR_FLAGS_REMOVABLE = IR_FLAG_EFFECT_FREE | IR_FLAG_NOTHROW | IR_FLAG_TERMINATES @@ -80,6 +81,9 @@ function flags_for_effects(effects::Effects) if is_noub(effects) flags |= IR_FLAG_NOUB end + if is_nortcall(effects) + flags |= IR_FLAG_NORTCALL + end return flags end @@ -249,9 +253,8 @@ end _topmod(sv::OptimizationState) = _topmod(sv.mod) -is_stmt_inline(stmt_flag::UInt32) = has_flag(stmt_flag, IR_FLAG_INLINE) -is_stmt_noinline(stmt_flag::UInt32) = has_flag(stmt_flag, IR_FLAG_NOINLINE) -is_stmt_throw_block(stmt_flag::UInt32) = has_flag(stmt_flag, IR_FLAG_THROW_BLOCK) +is_stmt_inline(stmt_flag::UInt32) = has_flag(stmt_flag, IR_FLAG_INLINE) +is_stmt_noinline(stmt_flag::UInt32) = has_flag(stmt_flag, IR_FLAG_NOINLINE) function new_expr_effect_flags(𝕃ₒ::AbstractLattice, args::Vector{Any}, src::Union{IRCode,IncrementalCompact}, pattern_match=nothing) Targ = args[1] @@ -586,26 +589,28 @@ mutable struct PostOptAnalysisState all_nothrow::Bool all_noub::Bool any_conditional_ub::Bool + nortcall::Bool function PostOptAnalysisState(result::InferenceResult, ir::IRCode) inconsistent = BitSetBoundedMinPrioritySet(length(ir.stmts)) tpdum = TwoPhaseDefUseMap(length(ir.stmts)) lazypostdomtree = LazyPostDomtree(ir) lazyagdomtree = LazyAugmentedDomtree(ir) return new(result, ir, inconsistent, tpdum, lazypostdomtree, lazyagdomtree, Int[], - true, true, nothing, true, true, false) + true, true, nothing, true, true, false, true) end end give_up_refinements!(sv::PostOptAnalysisState) = sv.all_retpaths_consistent = sv.all_effect_free = sv.effect_free_if_argmem_only = - sv.all_nothrow = sv.all_noub = false + sv.all_nothrow = sv.all_noub = sv.nortcall = false function any_refinable(sv::PostOptAnalysisState) effects = sv.result.ipo_effects return ((!is_consistent(effects) & sv.all_retpaths_consistent) | (!is_effect_free(effects) & sv.all_effect_free) | (!is_nothrow(effects) & sv.all_nothrow) | - (!is_noub(effects) & sv.all_noub)) + (!is_noub(effects) & sv.all_noub) | + (!is_nortcall(effects) & sv.nortcall)) end struct GetNativeEscapeCache{CodeCache} @@ -650,7 +655,8 @@ function refine_effects!(interp::AbstractInterpreter, sv::PostOptAnalysisState) effect_free = sv.all_effect_free ? ALWAYS_TRUE : sv.effect_free_if_argmem_only === true ? EFFECT_FREE_IF_INACCESSIBLEMEMONLY : effects.effect_free, nothrow = sv.all_nothrow ? true : effects.nothrow, - noub = sv.all_noub ? (sv.any_conditional_ub ? NOUB_IF_NOINBOUNDS : ALWAYS_TRUE) : effects.noub) + noub = sv.all_noub ? (sv.any_conditional_ub ? NOUB_IF_NOINBOUNDS : ALWAYS_TRUE) : effects.noub, + nortcall = sv.nortcall ? true : effects.nortcall) return true end @@ -775,6 +781,13 @@ function scan_non_dataflow_flags!(inst::Instruction, sv::PostOptAnalysisState) sv.all_noub = false end end + if !has_flag(flag, IR_FLAG_NORTCALL) + # if a function call that might invoke `Core.Compiler.return_type` has been deleted, + # there's no need to taint with `:nortcall`, allowing concrete evaluation + if isexpr(stmt, :call) || isexpr(stmt, :invoke) + sv.nortcall = false + end + end end function scan_inconsistency!(inst::Instruction, sv::PostOptAnalysisState) @@ -1272,7 +1285,7 @@ plus_saturate(x::Int, y::Int) = max(x, y, x+y) isknowntype(@nospecialize T) = (T === Union{}) || isa(T, Const) || isconcretetype(widenconst(T)) function statement_cost(ex::Expr, line::Int, src::Union{CodeInfo, IRCode}, sptypes::Vector{VarState}, - params::OptimizationParams, error_path::Bool = false) + params::OptimizationParams) #=const=# UNKNOWN_CALL_COST = 20 head = ex.head if is_meta_expr_head(head) @@ -1333,10 +1346,10 @@ function statement_cost(ex::Expr, line::Int, src::Union{CodeInfo, IRCode}, sptyp return 0 elseif (f === Core.memoryrefget || f === Core.memoryref_isassigned) && length(ex.args) >= 3 atyp = argextype(ex.args[2], src, sptypes) - return isknowntype(atyp) ? 1 : error_path ? params.inline_error_path_cost : params.inline_nonleaf_penalty + return isknowntype(atyp) ? 1 : params.inline_nonleaf_penalty elseif f === Core.memoryrefset! && length(ex.args) >= 3 atyp = argextype(ex.args[2], src, sptypes) - return isknowntype(atyp) ? 5 : error_path ? params.inline_error_path_cost : params.inline_nonleaf_penalty + return isknowntype(atyp) ? 5 : params.inline_nonleaf_penalty elseif f === typeassert && isconstType(widenconst(argextype(ex.args[3], src, sptypes))) return 1 end @@ -1352,7 +1365,7 @@ function statement_cost(ex::Expr, line::Int, src::Union{CodeInfo, IRCode}, sptyp if extyp === Union{} return 0 end - return error_path ? params.inline_error_path_cost : params.inline_nonleaf_penalty + return params.inline_nonleaf_penalty elseif head === :foreigncall foreigncall = ex.args[1] if foreigncall isa QuoteNode && foreigncall.value === :jl_string_ptr @@ -1375,7 +1388,7 @@ function statement_cost(ex::Expr, line::Int, src::Union{CodeInfo, IRCode}, sptyp end a = ex.args[2] if a isa Expr - cost = plus_saturate(cost, statement_cost(a, -1, src, sptypes, params, error_path)) + cost = plus_saturate(cost, statement_cost(a, -1, src, sptypes, params)) end return cost elseif head === :copyast @@ -1389,8 +1402,7 @@ function statement_or_branch_cost(@nospecialize(stmt), line::Int, src::Union{Cod thiscost = 0 dst(tgt) = isa(src, IRCode) ? first(src.cfg.blocks[tgt].stmts) : tgt if stmt isa Expr - thiscost = statement_cost(stmt, line, src, sptypes, params, - is_stmt_throw_block(isa(src, IRCode) ? src.stmts.flag[line] : src.ssaflags[line]))::Int + thiscost = statement_cost(stmt, line, src, sptypes, params)::Int elseif stmt isa GotoNode # loops are generally always expensive # but assume that forward jumps are already counted for from diff --git a/base/compiler/ssair/inlining.jl b/base/compiler/ssair/inlining.jl index a77a67ab262de..70318b9e1a979 100644 --- a/base/compiler/ssair/inlining.jl +++ b/base/compiler/ssair/inlining.jl @@ -1728,7 +1728,7 @@ function late_inline_special_case!(ir::IRCode, idx::Int, stmt::Expr, flag::UInt3 @nospecialize(type), sig::Signature, state::InliningState) OptimizationParams(state.interp).inlining || return nothing (; f, ft, argtypes) = sig - if length(argtypes) == 3 && istopfunction(f, :!==) + if length(argtypes) == 3 && f === Core.:(!==) # special-case inliner for !== that precedes _methods_by_ftype union splitting # and that works, even though inference generally avoids inferring the `!==` Method if isa(type, Const) @@ -1738,7 +1738,7 @@ function late_inline_special_case!(ir::IRCode, idx::Int, stmt::Expr, flag::UInt3 cmp_call_ssa = insert_node!(ir, idx, removable_if_unused(NewInstruction(cmp_call, Bool))) not_call = Expr(:call, GlobalRef(Core.Intrinsics, :not_int), cmp_call_ssa) return SomeCase(not_call) - elseif length(argtypes) == 3 && istopfunction(f, :(>:)) + elseif length(argtypes) == 3 && f === Core.:(>:) # special-case inliner for issupertype # that works, even though inference generally avoids inferring the `>:` Method if isa(type, Const) && has_flag(flag, IR_FLAG_NOTHROW) diff --git a/base/compiler/ssair/passes.jl b/base/compiler/ssair/passes.jl index 6b29c9b2fe949..33cda9bf27d20 100644 --- a/base/compiler/ssair/passes.jl +++ b/base/compiler/ssair/passes.jl @@ -79,7 +79,7 @@ end function find_curblock(domtree::DomTree, allblocks::BitSet, curblock::Int) # TODO: This can be much faster by looking at current level and only # searching for those blocks in a sorted order - while !(curblock in allblocks) && curblock !== 0 + while curblock ∉ allblocks && curblock ≠ 0 curblock = domtree.idoms_bb[curblock] end return curblock @@ -190,18 +190,21 @@ function collect_leaves(compact::IncrementalCompact, @nospecialize(val), @nospec return walk_to_defs(compact, val, typeconstraint, predecessors, 𝕃ₒ) end -function trivial_walker(@nospecialize(pi), @nospecialize(idx)) - return nothing -end +abstract type WalkerCallback end -function pi_walker(@nospecialize(pi), @nospecialize(idx)) - if isa(pi, PiNode) - return LiftedValue(pi.val) +struct TrivialWalker <: WalkerCallback end +(::TrivialWalker)(@nospecialize(def), @nospecialize(defssa::AnySSAValue)) = nothing + +struct PiWalker <: WalkerCallback end +function (::PiWalker)(@nospecialize(def), @nospecialize(defssa::AnySSAValue)) + if isa(def, PiNode) + return LiftedValue(def.val) end return nothing end -function simple_walk(compact::IncrementalCompact, @nospecialize(defssa#=::AnySSAValue=#), callback=trivial_walker) +function simple_walk(compact::IncrementalCompact, @nospecialize(defssa::AnySSAValue), + walker_callback::WalkerCallback=TrivialWalker()) while true if isa(defssa, OldSSAValue) if already_inserted(compact, defssa) @@ -218,7 +221,7 @@ function simple_walk(compact::IncrementalCompact, @nospecialize(defssa#=::AnySSA end def = compact[defssa][:stmt] if isa(def, AnySSAValue) - callback(def, defssa) + walker_callback(def, defssa) if isa(def, SSAValue) is_old(compact, defssa) && (def = OldSSAValue(def.id)) end @@ -226,7 +229,7 @@ function simple_walk(compact::IncrementalCompact, @nospecialize(defssa#=::AnySSA elseif isa(def, Union{PhiNode, PhiCNode, GlobalRef}) return defssa else - new_def = callback(def, defssa) + new_def = walker_callback(def, defssa) if new_def === nothing return defssa end @@ -241,16 +244,21 @@ function simple_walk(compact::IncrementalCompact, @nospecialize(defssa#=::AnySSA end end -function simple_walk_constraint(compact::IncrementalCompact, @nospecialize(defssa#=::AnySSAValue=#), - @nospecialize(typeconstraint)) - callback = function (@nospecialize(pi), @nospecialize(idx)) - if isa(pi, PiNode) - typeconstraint = typeintersect(typeconstraint, widenconst(pi.typ)) - return LiftedValue(pi.val) - end - return nothing +mutable struct TypeConstrainingWalker <: WalkerCallback + typeconstraint::Any + TypeConstrainingWalker(@nospecialize(typeconstraint::Any)) = new(typeconstraint) +end +function (walker_callback::TypeConstrainingWalker)(@nospecialize(def), @nospecialize(defssa::AnySSAValue)) + if isa(def, PiNode) + walker_callback.typeconstraint = + typeintersect(walker_callback.typeconstraint, widenconst(def.typ)) + return LiftedValue(def.val) end - def = simple_walk(compact, defssa, callback) + return nothing +end +function simple_walk_constraint(compact::IncrementalCompact, @nospecialize(val::AnySSAValue), + @nospecialize(typeconstraint)) + def = simple_walk(compact, val, TypeConstrainingWalker(typeconstraint)) return Pair{Any, Any}(def, typeconstraint) end @@ -638,15 +646,17 @@ end struct SkipToken end; const SKIP_TOKEN = SkipToken() -function lifted_value(compact::IncrementalCompact, @nospecialize(old_node_ssa#=::AnySSAValue=#), @nospecialize(old_value), - lifted_philikes::Vector{LiftedPhilike}, lifted_leaves::Union{LiftedLeaves, LiftedDefs}, reverse_mapping::IdDict{AnySSAValue, Int}, - walker_callback) +function lifted_value(compact::IncrementalCompact, @nospecialize(old_node_ssa::AnySSAValue), + @nospecialize(old_value), lifted_philikes::Vector{LiftedPhilike}, + lifted_leaves::Union{LiftedLeaves, LiftedDefs}, + reverse_mapping::IdDict{AnySSAValue, Int}, + walker_callback::WalkerCallback) val = old_value if is_old(compact, old_node_ssa) && isa(val, SSAValue) val = OldSSAValue(val.id) end if isa(val, AnySSAValue) - val = simple_walk(compact, val, def_walker(lifted_leaves, reverse_mapping, walker_callback)) + val = simple_walk(compact, val, LiftedLeaveWalker(lifted_leaves, reverse_mapping, walker_callback)) end if val in keys(lifted_leaves) lifted_val = lifted_leaves[val] @@ -656,7 +666,7 @@ function lifted_value(compact::IncrementalCompact, @nospecialize(old_node_ssa#=: lifted_val === nothing && return UNDEF_TOKEN val = lifted_val.val if isa(val, AnySSAValue) - val = simple_walk(compact, val, pi_walker) + val = simple_walk(compact, val, PiWalker()) end return val elseif isa(val, AnySSAValue) && val in keys(reverse_mapping) @@ -673,7 +683,7 @@ function is_old(compact, @nospecialize(old_node_ssa)) return true end -struct PhiNest{C} +struct PhiNest{C<:WalkerCallback} visited_philikes::Vector{AnySSAValue} lifted_philikes::Vector{LiftedPhilike} lifted_leaves::Union{LiftedLeaves, LiftedDefs} @@ -743,20 +753,29 @@ function finish_phi_nest!(compact::IncrementalCompact, nest::PhiNest) end end -function def_walker(lifted_leaves::Union{LiftedLeaves, LiftedDefs}, reverse_mapping::IdDict{AnySSAValue, Int}, walker_callback) - function (@nospecialize(walk_def), @nospecialize(defssa)) - if (defssa in keys(lifted_leaves)) || (isa(defssa, AnySSAValue) && defssa in keys(reverse_mapping)) - return nothing - end - isa(walk_def, PiNode) && return LiftedValue(walk_def.val) - return walker_callback(walk_def, defssa) +struct LiftedLeaveWalker{C<:WalkerCallback} <: WalkerCallback + lifted_leaves::Union{LiftedLeaves, LiftedDefs} + reverse_mapping::IdDict{AnySSAValue, Int} + inner_walker_callback::C + function LiftedLeaveWalker(@nospecialize(lifted_leaves::Union{LiftedLeaves, LiftedDefs}), + @nospecialize(reverse_mapping::IdDict{AnySSAValue, Int}), + inner_walker_callback::C) where C<:WalkerCallback + return new{C}(lifted_leaves, reverse_mapping, inner_walker_callback) end end +function (walker_callback::LiftedLeaveWalker)(@nospecialize(def), @nospecialize(defssa::AnySSAValue)) + (; lifted_leaves, reverse_mapping, inner_walker_callback) = walker_callback + if defssa in keys(lifted_leaves) || defssa in keys(reverse_mapping) + return nothing + end + isa(def, PiNode) && return LiftedValue(def.val) + return inner_walker_callback(def, defssa) +end function perform_lifting!(compact::IncrementalCompact, visited_philikes::Vector{AnySSAValue}, @nospecialize(cache_key), @nospecialize(result_t), lifted_leaves::Union{LiftedLeaves, LiftedDefs}, @nospecialize(stmt_val), - lazydomtree::Union{LazyDomtree,Nothing}, walker_callback = trivial_walker) + lazydomtree::Union{LazyDomtree,Nothing}, walker_callback::WalkerCallback = TrivialWalker()) reverse_mapping = IdDict{AnySSAValue, Int}() for id in 1:length(visited_philikes) reverse_mapping[visited_philikes[id]] = id @@ -839,7 +858,7 @@ function perform_lifting!(compact::IncrementalCompact, # Fixup the stmt itself if isa(stmt_val, Union{SSAValue, OldSSAValue}) - stmt_val = simple_walk(compact, stmt_val, def_walker(lifted_leaves, reverse_mapping, walker_callback)) + stmt_val = simple_walk(compact, stmt_val, LiftedLeaveWalker(lifted_leaves, reverse_mapping, walker_callback)) end if stmt_val in keys(lifted_leaves) @@ -948,6 +967,17 @@ function keyvalue_predecessors(@nospecialize(key), 𝕃ₒ::AbstractLattice) end end +struct KeyValueWalker <: WalkerCallback + compact::IncrementalCompact +end +function (walker_callback::KeyValueWalker)(@nospecialize(def), @nospecialize(defssa::AnySSAValue)) + if is_known_invoke_or_call(def, Core.OptimizedGenerics.KeyValue.set, walker_callback.compact) + @assert length(def.args) in (5, 6) + return LiftedValue(def.args[end-2]) + end + return nothing +end + function lift_keyvalue_get!(compact::IncrementalCompact, idx::Int, stmt::Expr, 𝕃ₒ::AbstractLattice) collection = stmt.args[end-1] key = stmt.args[end] @@ -964,16 +994,9 @@ function lift_keyvalue_get!(compact::IncrementalCompact, idx::Int, stmt::Expr, result_t = tmerge(𝕃ₒ, result_t, argextype(v.val, compact)) end - function keyvalue_walker(@nospecialize(def), _) - if is_known_invoke_or_call(def, Core.OptimizedGenerics.KeyValue.set, compact) - @assert length(def.args) in (5, 6) - return LiftedValue(def.args[end-2]) - end - return nothing - end (lifted_val, nest) = perform_lifting!(compact, visited_philikes, key, result_t, lifted_leaves, collection, nothing, - keyvalue_walker) + KeyValueWalker(compact)) compact[idx] = lifted_val === nothing ? nothing : Expr(:call, GlobalRef(Core, :tuple), lifted_val.val) finish_phi_nest!(compact, nest) @@ -1139,13 +1162,11 @@ end # which can be very large sometimes, and program counters in question are often very sparse const SPCSet = IdSet{Int} -struct IntermediaryCollector +struct IntermediaryCollector <: WalkerCallback intermediaries::SPCSet end -function (this::IntermediaryCollector)(@nospecialize(pi), @nospecialize(ssa)) - if !isa(pi, Expr) - push!(this.intermediaries, ssa.id) - end +function (walker_callback::IntermediaryCollector)(@nospecialize(def), @nospecialize(defssa::AnySSAValue)) + isa(def, Expr) || push!(walker_callback.intermediaries, defssa.id) return nothing end @@ -1242,7 +1263,7 @@ function sroa_pass!(ir::IRCode, inlining::Union{Nothing,InliningState}=nothing) update_scope_mapping!(scope_mapping, bb+1, bbs) end # check whether this statement is `getfield` / `setfield!` (or other "interesting" statement) - is_setfield = is_isdefined = is_finalizer = is_keyvalue_get = false + is_setfield = is_isdefined = is_finalizer = false field_ordering = :unspecified if is_known_call(stmt, setfield!, compact) 4 <= length(stmt.args) <= 5 || continue @@ -1371,8 +1392,7 @@ function sroa_pass!(ir::IRCode, inlining::Union{Nothing,InliningState}=nothing) if ismutabletypename(struct_typ_name) isa(val, SSAValue) || continue let intermediaries = SPCSet() - callback = IntermediaryCollector(intermediaries) - def = simple_walk(compact, val, callback) + def = simple_walk(compact, val, IntermediaryCollector(intermediaries)) # Mutable stuff here isa(def, SSAValue) || continue if defuses === nothing @@ -1680,7 +1700,7 @@ end function sroa_mutables!(ir::IRCode, defuses::IdDict{Int, Tuple{SPCSet, SSADefUse}}, used_ssas::Vector{Int}, lazydomtree::LazyDomtree, inlining::Union{Nothing, InliningState}) 𝕃ₒ = inlining === nothing ? SimpleInferenceLattice.instance : optimizer_lattice(inlining.interp) lazypostdomtree = LazyPostDomtree(ir) - for (idx, (intermediaries, defuse)) in defuses + for (defidx, (intermediaries, defuse)) in defuses intermediaries = collect(intermediaries) # Check if there are any uses we did not account for. If so, the variable # escapes and we cannot eliminate the allocation. This works, because we're guaranteed @@ -1688,16 +1708,15 @@ function sroa_mutables!(ir::IRCode, defuses::IdDict{Int, Tuple{SPCSet, SSADefUse # show up in the nuses_total count. nleaves = length(defuse.uses) + length(defuse.defs) nuses = 0 - for idx in intermediaries - nuses += used_ssas[idx] + for iidx in intermediaries + nuses += used_ssas[iidx] end - nuses_total = used_ssas[idx] + nuses - length(intermediaries) + nuses_total = used_ssas[defidx] + nuses - length(intermediaries) nleaves == nuses_total || continue # Find the type for this allocation - defexpr = ir[SSAValue(idx)][:stmt] + defexpr = ir[SSAValue(defidx)][:stmt] isexpr(defexpr, :new) || continue - newidx = idx - typ = unwrap_unionall(ir.stmts[newidx][:type]) + typ = unwrap_unionall(ir.stmts[defidx][:type]) # Could still end up here if we tried to setfield! on an immutable, which would # error at runtime, but is not illegal to have in the IR. typ = widenconst(typ) @@ -1713,7 +1732,7 @@ function sroa_mutables!(ir::IRCode, defuses::IdDict{Int, Tuple{SPCSet, SSADefUse end end if finalizer_idx !== nothing && inlining !== nothing - try_resolve_finalizer!(ir, idx, finalizer_idx, defuse, inlining, + try_resolve_finalizer!(ir, defidx, finalizer_idx, defuse, inlining, lazydomtree, lazypostdomtree, ir[SSAValue(finalizer_idx)][:info]) continue end @@ -1752,11 +1771,11 @@ function sroa_mutables!(ir::IRCode, defuses::IdDict{Int, Tuple{SPCSet, SSADefUse # but we should come up with semantics for well defined semantics # for uninitialized fields first. ndefuse = length(fielddefuse) - blocks = Vector{Tuple{#=phiblocks=# Vector{Int}, #=allblocks=# BitSet}}(undef, ndefuse) + blocks = Vector{Tuple{#=phiblocks=#Vector{Int},#=allblocks=#BitSet}}(undef, ndefuse) for fidx in 1:ndefuse du = fielddefuse[fidx] isempty(du.uses) && continue - push!(du.defs, newidx) + push!(du.defs, defidx) ldu = compute_live_ins(ir.cfg, du) if isempty(ldu.live_in_bbs) phiblocks = Int[] @@ -1769,7 +1788,7 @@ function sroa_mutables!(ir::IRCode, defuses::IdDict{Int, Tuple{SPCSet, SSADefUse for i = 1:length(du.uses) use = du.uses[i] if use.kind === :isdefined - if has_safe_def(ir, get!(lazydomtree), allblocks, du, newidx, use.idx) + if has_safe_def(ir, get!(lazydomtree), allblocks, du, defidx, use.idx) ir[SSAValue(use.idx)][:stmt] = true else all_eliminated = false @@ -1782,7 +1801,7 @@ function sroa_mutables!(ir::IRCode, defuses::IdDict{Int, Tuple{SPCSet, SSADefUse continue end end - has_safe_def(ir, get!(lazydomtree), allblocks, du, newidx, use.idx) || @goto skip + has_safe_def(ir, get!(lazydomtree), allblocks, du, defidx, use.idx) || @goto skip end else # always have some definition at the allocation site for i = 1:length(du.uses) @@ -1849,19 +1868,19 @@ function sroa_mutables!(ir::IRCode, defuses::IdDict{Int, Tuple{SPCSet, SSADefUse # all "usages" (i.e. `getfield` and `isdefined` calls) are eliminated, # now eliminate "definitions" (i.e. `setfield!`) calls # (NOTE the allocation itself will be eliminated by DCE pass later) - for idx in du.defs - idx == newidx && continue # this is allocation + for didx in du.defs + didx == defidx && continue # this is allocation # verify this statement won't throw, otherwise it can't be eliminated safely - ssa = SSAValue(idx) - if is_nothrow(ir, ssa) - ir[ssa][:stmt] = nothing + setfield_ssa = SSAValue(didx) + if is_nothrow(ir, setfield_ssa) + ir[setfield_ssa][:stmt] = nothing else # We can't eliminate this statement, because it might still # throw an error, but we can mark it as effect-free since we # know we have removed all uses of the mutable allocation. # As a result, if we ever do prove nothrow, we can delete # this statement then. - add_flag!(ir[ssa], IR_FLAG_EFFECT_FREE) + add_flag!(ir[setfield_ssa], IR_FLAG_EFFECT_FREE) end end end @@ -1870,7 +1889,7 @@ function sroa_mutables!(ir::IRCode, defuses::IdDict{Int, Tuple{SPCSet, SSADefUse # this means all ccall preserves have been replaced with forwarded loads # so we can potentially eliminate the allocation, otherwise we must preserve # the whole allocation. - push!(intermediaries, newidx) + push!(intermediaries, defidx) end # Insert the new preserves for (useidx, new_preserves) in preserve_uses diff --git a/base/compiler/ssair/show.jl b/base/compiler/ssair/show.jl index 82ca6e364f2fa..7d936a1688aba 100644 --- a/base/compiler/ssair/show.jl +++ b/base/compiler/ssair/show.jl @@ -1050,6 +1050,8 @@ function Base.show(io::IO, e::Effects) printstyled(io, effectbits_letter(e, :noub, 'u'); color=effectbits_color(e, :noub)) print(io, ',') printstyled(io, effectbits_letter(e, :nonoverlayed, 'o'); color=effectbits_color(e, :nonoverlayed)) + print(io, ',') + printstyled(io, effectbits_letter(e, :nortcall, 'r'); color=effectbits_color(e, :nortcall)) print(io, ')') end diff --git a/base/compiler/tfuncs.jl b/base/compiler/tfuncs.jl index 28e883d83312c..9a4c761b4209b 100644 --- a/base/compiler/tfuncs.jl +++ b/base/compiler/tfuncs.jl @@ -227,10 +227,19 @@ end @nospecs shift_tfunc(𝕃::AbstractLattice, x, y) = shift_tfunc(widenlattice(𝕃), x, y) @nospecs shift_tfunc(::JLTypeLattice, x, y) = widenconst(x) +function not_tfunc(𝕃::AbstractLattice, @nospecialize(b)) + if isa(b, Conditional) + return Conditional(b.slot, b.elsetype, b.thentype) + elseif isa(b, Const) + return Const(not_int(b.val)) + end + return math_tfunc(𝕃, b) +end + add_tfunc(and_int, 2, 2, and_int_tfunc, 1) add_tfunc(or_int, 2, 2, or_int_tfunc, 1) add_tfunc(xor_int, 2, 2, math_tfunc, 1) -add_tfunc(not_int, 1, 1, math_tfunc, 0) # usually used as not_int(::Bool) to negate a condition +add_tfunc(not_int, 1, 1, not_tfunc, 0) # usually used as not_int(::Bool) to negate a condition add_tfunc(shl_int, 2, 2, shift_tfunc, 1) add_tfunc(lshr_int, 2, 2, shift_tfunc, 1) add_tfunc(ashr_int, 2, 2, shift_tfunc, 1) @@ -2862,7 +2871,7 @@ end # since abstract_call_gf_by_type is a very inaccurate model of _method and of typeinf_type, # while this assumes that it is an absolutely precise and accurate and exact model of both function return_type_tfunc(interp::AbstractInterpreter, argtypes::Vector{Any}, si::StmtInfo, sv::AbsIntState) - UNKNOWN = CallMeta(Type, Any, EFFECTS_THROWS, NoCallInfo()) + UNKNOWN = CallMeta(Type, Any, Effects(EFFECTS_THROWS; nortcall=false), NoCallInfo()) if !(2 <= length(argtypes) <= 3) return UNKNOWN end @@ -2890,8 +2899,12 @@ function return_type_tfunc(interp::AbstractInterpreter, argtypes::Vector{Any}, s return UNKNOWN end + # effects are not an issue if we know this statement will get removed, but if it does not get removed, + # then this could be recursively re-entering inference (via concrete-eval), which will not terminate + RT_CALL_EFFECTS = Effects(EFFECTS_TOTAL; nortcall=false) + if contains_is(argtypes_vec, Union{}) - return CallMeta(Const(Union{}), Union{}, EFFECTS_TOTAL, NoCallInfo()) + return CallMeta(Const(Union{}), Union{}, RT_CALL_EFFECTS, NoCallInfo()) end # Run the abstract_call without restricting abstract call @@ -2909,25 +2922,25 @@ function return_type_tfunc(interp::AbstractInterpreter, argtypes::Vector{Any}, s rt = widenslotwrapper(call.rt) if isa(rt, Const) # output was computed to be constant - return CallMeta(Const(typeof(rt.val)), Union{}, EFFECTS_TOTAL, info) + return CallMeta(Const(typeof(rt.val)), Union{}, RT_CALL_EFFECTS, info) end rt = widenconst(rt) if rt === Bottom || (isconcretetype(rt) && !iskindtype(rt)) # output cannot be improved so it is known for certain - return CallMeta(Const(rt), Union{}, EFFECTS_TOTAL, info) + return CallMeta(Const(rt), Union{}, RT_CALL_EFFECTS, info) elseif isa(sv, InferenceState) && !isempty(sv.pclimitations) # conservatively express uncertainty of this result # in two ways: both as being a subtype of this, and # because of LimitedAccuracy causes - return CallMeta(Type{<:rt}, Union{}, EFFECTS_TOTAL, info) + return CallMeta(Type{<:rt}, Union{}, RT_CALL_EFFECTS, info) elseif isa(tt, Const) || isconstType(tt) # input arguments were known for certain # XXX: this doesn't imply we know anything about rt - return CallMeta(Const(rt), Union{}, EFFECTS_TOTAL, info) + return CallMeta(Const(rt), Union{}, RT_CALL_EFFECTS, info) elseif isType(rt) - return CallMeta(Type{rt}, Union{}, EFFECTS_TOTAL, info) + return CallMeta(Type{rt}, Union{}, RT_CALL_EFFECTS, info) else - return CallMeta(Type{<:rt}, Union{}, EFFECTS_TOTAL, info) + return CallMeta(Type{<:rt}, Union{}, RT_CALL_EFFECTS, info) end end diff --git a/base/compiler/typeinfer.jl b/base/compiler/typeinfer.jl index 77547a5b30877..41fb774266f25 100644 --- a/base/compiler/typeinfer.jl +++ b/base/compiler/typeinfer.jl @@ -449,6 +449,9 @@ function adjust_effects(ipo_effects::Effects, def::Method) if is_effect_overridden(override, :consistent_overlay) ipo_effects = Effects(ipo_effects; nonoverlayed=CONSISTENT_OVERLAY) end + if is_effect_overridden(override, :nortcall) + ipo_effects = Effects(ipo_effects; nortcall=true) + end return ipo_effects end @@ -1118,7 +1121,7 @@ const SOURCE_MODE_FORCE_SOURCE = 0x2 function ci_has_source(code::CodeInstance) inf = @atomic :monotonic code.inferred - return isa(inf, CodeInfo) || isa(inf, String) + return code.owner === nothing ? (isa(inf, CodeInfo) || isa(inf, String)) : inf !== nothing end """ diff --git a/base/compiler/types.jl b/base/compiler/types.jl index 7021601bf87cf..f315b7968fd9b 100644 --- a/base/compiler/types.jl +++ b/base/compiler/types.jl @@ -156,11 +156,6 @@ Parameters that control abstract interpretation-based type inference operation. information available. [`Base.@constprop :aggressive`](@ref Base.@constprop) can have a more fine-grained control on this configuration with per-method annotation basis. --- -- `inf_params.unoptimize_throw_blocks::Bool = true`\\ - If `true`, skips inferring calls that are in a block that is known to `throw`. - It may improve the compiler latency without sacrificing the runtime performance - in common situations. ---- - `inf_params.assume_bindings_static::Bool = false`\\ If `true`, assumes that no new bindings will be added, i.e. a non-existing binding at inference time can be assumed to always not exist at runtime (and thus e.g. any access to @@ -176,7 +171,6 @@ struct InferenceParams tuple_complexity_limit_depth::Int ipo_constant_propagation::Bool aggressive_constant_propagation::Bool - unoptimize_throw_blocks::Bool assume_bindings_static::Bool ignore_recursion_hardlimit::Bool @@ -188,7 +182,6 @@ struct InferenceParams tuple_complexity_limit_depth::Int, ipo_constant_propagation::Bool, aggressive_constant_propagation::Bool, - unoptimize_throw_blocks::Bool, assume_bindings_static::Bool, ignore_recursion_hardlimit::Bool) return new( @@ -199,7 +192,6 @@ struct InferenceParams tuple_complexity_limit_depth, ipo_constant_propagation, aggressive_constant_propagation, - unoptimize_throw_blocks, assume_bindings_static, ignore_recursion_hardlimit) end @@ -213,7 +205,6 @@ function InferenceParams( #=tuple_complexity_limit_depth::Int=# 3, #=ipo_constant_propagation::Bool=# true, #=aggressive_constant_propagation::Bool=# false, - #=unoptimize_throw_blocks::Bool=# BuildSettings.UNOPTIMIZE_THROW_BLOCKS, #=assume_bindings_static::Bool=# false, #=ignore_recursion_hardlimit::Bool=# false); max_methods::Int = params.max_methods, @@ -223,7 +214,6 @@ function InferenceParams( tuple_complexity_limit_depth::Int = params.tuple_complexity_limit_depth, ipo_constant_propagation::Bool = params.ipo_constant_propagation, aggressive_constant_propagation::Bool = params.aggressive_constant_propagation, - unoptimize_throw_blocks::Bool = params.unoptimize_throw_blocks, assume_bindings_static::Bool = params.assume_bindings_static, ignore_recursion_hardlimit::Bool = params.ignore_recursion_hardlimit) return InferenceParams( @@ -234,7 +224,6 @@ function InferenceParams( tuple_complexity_limit_depth, ipo_constant_propagation, aggressive_constant_propagation, - unoptimize_throw_blocks, assume_bindings_static, ignore_recursion_hardlimit) end @@ -259,10 +248,6 @@ Parameters that control optimizer operation. tuple return types (in hopes of splitting it up). `opt_params.inline_tupleret_bonus` will be added to `opt_params.inline_cost_threshold` when making inlining decision. --- -- `opt_params.inline_error_path_cost::Int = 20`\\ - Specifies the penalty cost for an un-optimized dynamic call in a block that is known to - `throw`. See also [`(inf_params::InferenceParams).unoptimize_throw_blocks`](@ref InferenceParams). ---- - `opt_params.max_tuple_splat::Int = 32`\\ When attempting to inline `Core._apply_iterate`, abort the optimization if the tuple contains more than this many elements. @@ -289,7 +274,6 @@ struct OptimizationParams inline_cost_threshold::Int inline_nonleaf_penalty::Int inline_tupleret_bonus::Int - inline_error_path_cost::Int max_tuple_splat::Int compilesig_invokes::Bool assume_fatal_throw::Bool @@ -300,7 +284,6 @@ struct OptimizationParams inline_cost_threshold::Int, inline_nonleaf_penalty::Int, inline_tupleret_bonus::Int, - inline_error_path_cost::Int, max_tuple_splat::Int, compilesig_invokes::Bool, assume_fatal_throw::Bool, @@ -310,7 +293,6 @@ struct OptimizationParams inline_cost_threshold, inline_nonleaf_penalty, inline_tupleret_bonus, - inline_error_path_cost, max_tuple_splat, compilesig_invokes, assume_fatal_throw, @@ -323,7 +305,6 @@ function OptimizationParams( #=inline_cost_threshold::Int=# 100, #=inline_nonleaf_penalty::Int=# 1000, #=inline_tupleret_bonus::Int=# 250, - #=inline_error_path_cost::Int=# 20, #=max_tuple_splat::Int=# 32, #=compilesig_invokes::Bool=# true, #=assume_fatal_throw::Bool=# false, @@ -332,7 +313,6 @@ function OptimizationParams( inline_cost_threshold::Int = params.inline_cost_threshold, inline_nonleaf_penalty::Int = params.inline_nonleaf_penalty, inline_tupleret_bonus::Int = params.inline_tupleret_bonus, - inline_error_path_cost::Int = params.inline_error_path_cost, max_tuple_splat::Int = params.max_tuple_splat, compilesig_invokes::Bool = params.compilesig_invokes, assume_fatal_throw::Bool = params.assume_fatal_throw, @@ -342,7 +322,6 @@ function OptimizationParams( inline_cost_threshold, inline_nonleaf_penalty, inline_tupleret_bonus, - inline_error_path_cost, max_tuple_splat, compilesig_invokes, assume_fatal_throw, diff --git a/base/compiler/utilities.jl b/base/compiler/utilities.jl index 527c6ab42eb2d..b3dfd73d53452 100644 --- a/base/compiler/utilities.jl +++ b/base/compiler/utilities.jl @@ -48,15 +48,6 @@ anymap(f::Function, a::Array{Any,1}) = Any[ f(a[i]) for i in 1:length(a) ] _topmod(m::Module) = ccall(:jl_base_relative_to, Any, (Any,), m)::Module -function istopfunction(@nospecialize(f), name::Symbol) - tn = typeof(f).name - if tn.mt.name === name - top = _topmod(tn.module) - return isdefined(top, name) && isconst(top, name) && f === getglobal(top, name) - end - return false -end - ####### # AST # ####### diff --git a/base/complex.jl b/base/complex.jl index 8ac126d2c6532..095c842795d38 100644 --- a/base/complex.jl +++ b/base/complex.jl @@ -1037,24 +1037,22 @@ end function atanh(z::Complex{T}) where T z = float(z) Tf = float(T) - Ω = prevfloat(typemax(Tf)) - θ = sqrt(Ω)/4 - ρ = 1/θ x, y = reim(z) ax = abs(x) ay = abs(y) + θ = sqrt(floatmax(Tf))/4 if ax > θ || ay > θ #Prevent overflow if isnan(y) if isinf(x) return Complex(copysign(zero(x),x), y) else - return Complex(real(1/z), y) + return Complex(real(inv(z)), y) end end if isinf(y) return Complex(copysign(zero(x),x), copysign(oftype(y,pi)/2, y)) end - return Complex(real(1/z), copysign(oftype(y,pi)/2, y)) + return Complex(real(inv(z)), copysign(oftype(y,pi)/2, y)) end β = copysign(one(Tf), x) z *= β @@ -1064,16 +1062,15 @@ function atanh(z::Complex{T}) where T ξ = oftype(x, Inf) η = y else - ym = ay+ρ - ξ = log(sqrt(sqrt(4+y*y))/sqrt(ym)) - η = copysign(oftype(y,pi)/2 + atan(ym/2), y)/2 + ξ = log(sqrt(sqrt(muladd(y, y, 4)))/sqrt(ay)) + η = copysign(oftype(y,pi)/2 + atan(ay/2), y)/2 end else #Normal case - ysq = (ay+ρ)^2 + ysq = ay^2 if x == 0 ξ = x else - ξ = log1p(4x/((1-x)^2 + ysq))/4 + ξ = log1p(4x/(muladd(1-x, 1-x, ysq)))/4 end η = angle(Complex((1-x)*(1+x)-ysq, 2y))/2 end diff --git a/base/docs/basedocs.jl b/base/docs/basedocs.jl index dd4c8d64e7d4e..e03d0db78f29f 100644 --- a/base/docs/basedocs.jl +++ b/base/docs/basedocs.jl @@ -663,8 +663,11 @@ kw"{", kw"{}", kw"}" """ [] -Square braces are used for [indexing](@ref man-array-indexing), [indexed assignment](@ref man-indexed-assignment), -[array literals](@ref man-array-literals), and [array comprehensions](@ref man-comprehensions). +Square brackets are used for [indexing](@ref man-array-indexing) ([`getindex`](@ref)), +[indexed assignment](@ref man-indexed-assignment) ([`setindex!`](@ref)), +[array literals](@ref man-array-literals) ([`Base.vect`](@ref)), +[array concatenation](@ref man-array-concatenation) ([`vcat`](@ref), [`hcat`](@ref), [`hvcat`](@ref), [`hvncat`](@ref)), +and [array comprehensions](@ref man-comprehensions) ([`collect`](@ref)). """ kw"[", kw"[]", kw"]" @@ -3185,14 +3188,27 @@ Any """ Union{} -`Union{}`, the empty [`Union`](@ref) of types, is the type that has no values. That is, it has the defining -property `isa(x, Union{}) == false` for any `x`. `Base.Bottom` is defined as its alias and the type of `Union{}` -is `Core.TypeofBottom`. +`Union{}`, the empty [`Union`](@ref) of types, is the *bottom* type of the type system. That is, for each +`T::Type`, `Union{} <: T`. Also see the subtyping operator's documentation: [`<:`](@ref). + +As such, `Union{}` is also an *empty*/*uninhabited* type, meaning that it has no values. That is, for each `x`, +`isa(x, Union{}) == false`. + +`Base.Bottom` is defined as its alias and the type of `Union{}` is `Core.TypeofBottom`. # Examples ```jldoctest julia> isa(nothing, Union{}) false + +julia> Union{} <: Int +true + +julia> typeof(Union{}) === Core.TypeofBottom +true + +julia> isa(Union{}, Union) +false ``` """ kw"Union{}", Base.Bottom diff --git a/base/errorshow.jl b/base/errorshow.jl index fc9fc5c2aac32..a3bf464439d44 100644 --- a/base/errorshow.jl +++ b/base/errorshow.jl @@ -43,6 +43,15 @@ function showerror(io::IO, ex::Meta.ParseError) end end +function showerror(io::IO, ex::Core.TypeNameError) + print(io, "TypeNameError: ") + if isa(ex.a, Union) + print(io, "typename does not apply to unions whose components have different typenames") + else + print(io, "typename does not apply to this type") + end +end + function showerror(io::IO, ex::BoundsError) print(io, "BoundsError") if isdefined(ex, :a) diff --git a/base/essentials.jl b/base/essentials.jl index c4ce6dfbd4e3a..32c44a9571f23 100644 --- a/base/essentials.jl +++ b/base/essentials.jl @@ -202,7 +202,8 @@ macro _total_meta() #=:inaccessiblememonly=#true, #=:noub=#true, #=:noub_if_noinbounds=#false, - #=:consistent_overlay=#false)) + #=:consistent_overlay=#false, + #=:nortcall=#true)) end # can be used in place of `@assume_effects :foldable` (supposed to be used for bootstrapping) macro _foldable_meta() @@ -216,7 +217,8 @@ macro _foldable_meta() #=:inaccessiblememonly=#true, #=:noub=#true, #=:noub_if_noinbounds=#false, - #=:consistent_overlay=#false)) + #=:consistent_overlay=#false, + #=:nortcall=#true)) end # can be used in place of `@assume_effects :terminates_locally` (supposed to be used for bootstrapping) macro _terminates_locally_meta() @@ -230,7 +232,8 @@ macro _terminates_locally_meta() #=:inaccessiblememonly=#false, #=:noub=#false, #=:noub_if_noinbounds=#false, - #=:consistent_overlay=#false)) + #=:consistent_overlay=#false, + #=:nortcall=#false)) end # can be used in place of `@assume_effects :terminates_globally` (supposed to be used for bootstrapping) macro _terminates_globally_meta() @@ -244,7 +247,8 @@ macro _terminates_globally_meta() #=:inaccessiblememonly=#false, #=:noub=#false, #=:noub_if_noinbounds=#false, - #=:consistent_overlay=#false)) + #=:consistent_overlay=#false, + #=:nortcall=#false)) end # can be used in place of `@assume_effects :terminates_globally :notaskstate` (supposed to be used for bootstrapping) macro _terminates_globally_notaskstate_meta() @@ -258,7 +262,8 @@ macro _terminates_globally_notaskstate_meta() #=:inaccessiblememonly=#false, #=:noub=#false, #=:noub_if_noinbounds=#false, - #=:consistent_overlay=#false)) + #=:consistent_overlay=#false, + #=:nortcall=#false)) end # can be used in place of `@assume_effects :terminates_globally :noub` (supposed to be used for bootstrapping) macro _terminates_globally_noub_meta() @@ -272,7 +277,8 @@ macro _terminates_globally_noub_meta() #=:inaccessiblememonly=#false, #=:noub=#true, #=:noub_if_noinbounds=#false, - #=:consistent_overlay=#false)) + #=:consistent_overlay=#false, + #=:nortcall=#false)) end # can be used in place of `@assume_effects :effect_free :terminates_locally` (supposed to be used for bootstrapping) macro _effect_free_terminates_locally_meta() @@ -286,7 +292,8 @@ macro _effect_free_terminates_locally_meta() #=:inaccessiblememonly=#false, #=:noub=#false, #=:noub_if_noinbounds=#false, - #=:consistent_overlay=#false)) + #=:consistent_overlay=#false, + #=:nortcall=#false)) end # can be used in place of `@assume_effects :nothrow :noub` (supposed to be used for bootstrapping) macro _nothrow_noub_meta() @@ -300,7 +307,8 @@ macro _nothrow_noub_meta() #=:inaccessiblememonly=#false, #=:noub=#true, #=:noub_if_noinbounds=#false, - #=:consistent_overlay=#false)) + #=:consistent_overlay=#false, + #=:nortcall=#false)) end # can be used in place of `@assume_effects :nothrow` (supposed to be used for bootstrapping) macro _nothrow_meta() @@ -314,7 +322,8 @@ macro _nothrow_meta() #=:inaccessiblememonly=#false, #=:noub=#false, #=:noub_if_noinbounds=#false, - #=:consistent_overlay=#false)) + #=:consistent_overlay=#false, + #=:nortcall=#false)) end # can be used in place of `@assume_effects :nothrow` (supposed to be used for bootstrapping) macro _noub_meta() @@ -342,7 +351,8 @@ macro _notaskstate_meta() #=:inaccessiblememonly=#false, #=:noub=#false, #=:noub_if_noinbounds=#false, - #=:consistent_overlay=#false)) + #=:consistent_overlay=#false, + #=:nortcall=#false)) end # can be used in place of `@assume_effects :noub_if_noinbounds` (supposed to be used for bootstrapping) macro _noub_if_noinbounds_meta() @@ -356,7 +366,8 @@ macro _noub_if_noinbounds_meta() #=:inaccessiblememonly=#false, #=:noub=#false, #=:noub_if_noinbounds=#true, - #=:consistent_overlay=#false)) + #=:consistent_overlay=#false, + #=:nortcall=#false)) end # another version of inlining that propagates an inbounds context @@ -389,7 +400,7 @@ julia> nameof(Base.Broadcast) """ nameof(m::Module) = (@_total_meta; ccall(:jl_module_name, Ref{Symbol}, (Any,), m)) -function iterate end +typeof(function iterate end).name.constprop_heuristic = Core.ITERATE_HEURISTIC """ convert(T, x) @@ -575,15 +586,7 @@ function unconstrain_vararg_length(va::Core.TypeofVararg) return Vararg{unwrapva(va)} end -typename(a) = error("typename does not apply to this type") -typename(a::DataType) = a.name -function typename(a::Union) - ta = typename(a.a) - tb = typename(a.b) - ta === tb || error("typename does not apply to unions whose components have different typenames") - return tb -end -typename(union::UnionAll) = typename(union.body) +import Core: typename _tuple_error(T::Type, x) = (@noinline; throw(MethodError(convert, (T, x)))) @@ -1245,3 +1248,16 @@ that is whether it has an `iterate` method or not. function isiterable(T)::Bool return hasmethod(iterate, Tuple{T}) end + +# Special constprop heuristics for various binary opes +typename(typeof(function + end)).constprop_heuristic = Core.SAMETYPE_HEURISTIC +typename(typeof(function - end)).constprop_heuristic = Core.SAMETYPE_HEURISTIC +typename(typeof(function * end)).constprop_heuristic = Core.SAMETYPE_HEURISTIC +typename(typeof(function == end)).constprop_heuristic = Core.SAMETYPE_HEURISTIC +typename(typeof(function != end)).constprop_heuristic = Core.SAMETYPE_HEURISTIC +typename(typeof(function <= end)).constprop_heuristic = Core.SAMETYPE_HEURISTIC +typename(typeof(function >= end)).constprop_heuristic = Core.SAMETYPE_HEURISTIC +typename(typeof(function < end)).constprop_heuristic = Core.SAMETYPE_HEURISTIC +typename(typeof(function > end)).constprop_heuristic = Core.SAMETYPE_HEURISTIC +typename(typeof(function << end)).constprop_heuristic = Core.SAMETYPE_HEURISTIC +typename(typeof(function >> end)).constprop_heuristic = Core.SAMETYPE_HEURISTIC diff --git a/base/exports.jl b/base/exports.jl index 1f0ccdf6b8c36..daba9a010a9e6 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -407,6 +407,7 @@ export indexin, argmax, argmin, + insertdims, invperm, invpermute!, isassigned, @@ -595,6 +596,7 @@ export codepoint, codeunit, codeunits, + ctruncate, digits, digits!, eachsplit, @@ -619,6 +621,7 @@ export join, lpad, lstrip, + ltruncate, ncodeunits, ndigits, nextind, @@ -631,6 +634,7 @@ export rpad, rsplit, rstrip, + rtruncate, split, string, strip, diff --git a/base/expr.jl b/base/expr.jl index 7d723c3f940d7..c4f64b89de8b6 100644 --- a/base/expr.jl +++ b/base/expr.jl @@ -505,6 +505,7 @@ The following `setting`s are supported. - `:inaccessiblememonly` - `:noub` - `:noub_if_noinbounds` +- `:nortcall` - `:foldable` - `:removable` - `:total` @@ -673,6 +674,20 @@ The `:noub` setting asserts that the method will not execute any undefined behav any other effect assertions (such as `:consistent` or `:effect_free`) as well, but we do not model this, and they assume the absence of undefined behavior. +--- +## `:nortcall` + +The `:nortcall` setting asserts that the method does not call `Core.Compiler.return_type`, +and that any other methods this method might call also do not call `Core.Compiler.return_type`. + +!!! note + To be precise, this assertion can be used when a call to `Core.Compiler.return_type` is + not made at runtime; that is, when the result of `Core.Compiler.return_type` is known + exactly at compile time and the call is eliminated by the optimizer. However, since + whether the result of `Core.Compiler.return_type` is folded at compile time depends + heavily on the compiler's implementation, it is generally risky to assert this if + the method in question uses `Core.Compiler.return_type` in any form. + --- ## `:foldable` @@ -683,6 +698,7 @@ currently equivalent to the following `setting`s: - `:effect_free` - `:terminates_globally` - `:noub` +- `:nortcall` !!! note This list in particular does not include `:nothrow`. The compiler will still @@ -716,6 +732,7 @@ the following other `setting`s: - `:notaskstate` - `:inaccessiblememonly` - `:noub` +- `:nortcall` !!! warning `:total` is a very strong assertion and will likely gain additional semantics @@ -794,17 +811,17 @@ function compute_assumed_setting(override::EffectsOverride, @nospecialize(settin elseif setting === :noub_if_noinbounds return EffectsOverride(override; noub_if_noinbounds = val) elseif setting === :foldable - consistent = effect_free = terminates_globally = noub = val - return EffectsOverride(override; consistent, effect_free, terminates_globally, noub) + consistent = effect_free = terminates_globally = noub = nortcall = val + return EffectsOverride(override; consistent, effect_free, terminates_globally, noub, nortcall) elseif setting === :removable effect_free = nothrow = terminates_globally = val return EffectsOverride(override; effect_free, nothrow, terminates_globally) elseif setting === :total consistent = effect_free = nothrow = terminates_globally = notaskstate = - inaccessiblememonly = noub = val + inaccessiblememonly = noub = nortcall = val return EffectsOverride(override; consistent, effect_free, nothrow, terminates_globally, notaskstate, - inaccessiblememonly, noub) + inaccessiblememonly, noub, nortcall) end return nothing end diff --git a/base/file.jl b/base/file.jl index e1b8e8a748fae..3987029d5f74f 100644 --- a/base/file.jl +++ b/base/file.jl @@ -440,11 +440,61 @@ julia> rm("goodbye.txt"); ``` """ function mv(src::AbstractString, dst::AbstractString; force::Bool=false) - checkfor_mv_cp_cptree(src, dst, "moving"; force=force) - rename(src, dst) + if force + _mv_replace(src, dst) + else + _mv_noreplace(src, dst) + end +end + +function _mv_replace(src::AbstractString, dst::AbstractString) + # This check is copied from checkfor_mv_cp_cptree + if ispath(dst) && Base.samefile(src, dst) + abs_src = islink(src) ? abspath(readlink(src)) : abspath(src) + abs_dst = islink(dst) ? abspath(readlink(dst)) : abspath(dst) + throw(ArgumentError(string("'src' and 'dst' refer to the same file/dir. ", + "This is not supported.\n ", + "`src` refers to: $(abs_src)\n ", + "`dst` refers to: $(abs_dst)\n"))) + end + # First try to do a regular rename, because this might avoid a situation + # where dst is deleted or truncated. + try + rename(src, dst) + catch err + err isa IOError || rethrow() + err.code==Base.UV_ENOENT && rethrow() + # on rename error try to delete dst if it exists and isn't the same as src + checkfor_mv_cp_cptree(src, dst, "moving"; force=true) + try + rename(src, dst) + catch err + err isa IOError || rethrow() + # on second error, default to force cp && rm + cp(src, dst; force=true, follow_symlinks=false) + rm(src; recursive=true) + end + end + dst +end + +function _mv_noreplace(src::AbstractString, dst::AbstractString) + # Error if dst exists. + # This check currently has TOCTTOU issues. + checkfor_mv_cp_cptree(src, dst, "moving"; force=false) + try + rename(src, dst) + catch err + err isa IOError || rethrow() + err.code==Base.UV_ENOENT && rethrow() + # on error, default to cp && rm + cp(src, dst; force=false, follow_symlinks=false) + rm(src; recursive=true) + end dst end + """ touch(path::AbstractString) touch(fd::File) @@ -1126,15 +1176,24 @@ function unlink(p::AbstractString) nothing end -# For move command -function rename(src::AbstractString, dst::AbstractString; force::Bool=false) - err = ccall(:jl_fs_rename, Int32, (Cstring, Cstring), src, dst) - # on error, default to cp && rm +""" + 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. +Return `newpath`. + +OS-specific restrictions may apply when `oldpath` and `newpath` are in different directories. + +See also: [`mv`](@ref). +""" +function rename(oldpath::AbstractString, newpath::AbstractString) + err = ccall(:jl_fs_rename, Int32, (Cstring, Cstring), oldpath, newpath) if err < 0 - cp(src, dst; force=force, follow_symlinks=false) - rm(src; recursive=true) + uv_error("rename($(repr(oldpath)), $(repr(newpath)))", err) end - nothing + newpath end function sendfile(src::AbstractString, dst::AbstractString) diff --git a/base/floatfuncs.jl b/base/floatfuncs.jl index a2a0f60bcf399..67e7899b4107c 100644 --- a/base/floatfuncs.jl +++ b/base/floatfuncs.jl @@ -42,7 +42,7 @@ it is the minimum of `maxintfloat(T)` and [`typemax(S)`](@ref). maxintfloat(::Type{S}, ::Type{T}) where {S<:AbstractFloat, T<:Integer} = min(maxintfloat(S), S(typemax(T))) maxintfloat() = maxintfloat(Float64) -isinteger(x::AbstractFloat) = (x - trunc(x) == 0) +isinteger(x::AbstractFloat) = iszero(x - trunc(x)) # note: x == trunc(x) would be incorrect for x=Inf # See rounding.jl for docstring. diff --git a/base/genericmemory.jl b/base/genericmemory.jl index 32c15a22e0db1..6537839320206 100644 --- a/base/genericmemory.jl +++ b/base/genericmemory.jl @@ -71,6 +71,8 @@ size(a::GenericMemory) = (length(a),) IndexStyle(::Type{<:GenericMemory}) = IndexLinear() +parent(ref::GenericMemoryRef) = ref.mem + pointer(mem::GenericMemoryRef) = unsafe_convert(Ptr{Cvoid}, mem) # no bounds check, even for empty array _unsetindex!(A::Memory, i::Int) = (@_propagate_inbounds_meta; _unsetindex!(memoryref(A, i)); A) @@ -316,31 +318,6 @@ function indcopy(sz::Dims, I::GenericMemory) dst, src end -# Wrapping a memory region in an Array -@eval begin # @eval for the Array construction. Block for the docstring. - function reshape(m::GenericMemory{M, T}, dims::Vararg{Int, N}) where {M, T, N} - len = Core.checked_dims(dims...) - length(m) == len || throw(DimensionMismatch("parent has $(length(m)) elements, which is incompatible with size $(dims)")) - ref = memoryref(m) - $(Expr(:new, :(Array{T, N}), :ref, :dims)) - end - - """ - view(m::GenericMemory{M, T}, inds::Union{UnitRange, OneTo}) - - Create a vector `v::Vector{T}` backed by the specified indices of `m`. It is only safe to - resize `v` if `m` is subseqently not used. - """ - function view(m::GenericMemory{M, T}, inds::Union{UnitRange, OneTo}) where {M, T} - isempty(inds) && return T[] # needed to allow view(Memory{T}(undef, 0), 2:1) - @boundscheck checkbounds(m, inds) - ref = memoryref(m, first(inds)) # @inbounds would be safe here but does not help performance. - dims = (Int(length(inds)),) - $(Expr(:new, :(Array{T, 1}), :ref, :dims)) - end -end -view(m::GenericMemory, inds::Colon) = view(m, eachindex(m)) - # get, set(once), modify, swap and replace at index, atomically function getindex_atomic(mem::GenericMemory, order::Symbol, i::Int) memref = memoryref(mem, i) diff --git a/base/intfuncs.jl b/base/intfuncs.jl index c73ef68551266..f72ac6ee08d4d 100644 --- a/base/intfuncs.jl +++ b/base/intfuncs.jl @@ -1237,3 +1237,102 @@ function binomial(x::Number, k::Integer) # and instead divide each term by i, to avoid spurious overflow. return prod(i -> (x-(i-1))/i, OneTo(k), init=oneunit(x)/one(k)) end + +""" + clamp(x, lo, hi) + +Return `x` if `lo <= x <= hi`. If `x > hi`, return `hi`. If `x < lo`, return `lo`. Arguments +are promoted to a common type. + +See also [`clamp!`](@ref), [`min`](@ref), [`max`](@ref). + +!!! compat "Julia 1.3" + `missing` as the first argument requires at least Julia 1.3. + +# Examples +```jldoctest +julia> clamp.([pi, 1.0, big(10)], 2.0, 9.0) +3-element Vector{BigFloat}: + 3.141592653589793238462643383279502884197169399375105820974944592307816406286198 + 2.0 + 9.0 + +julia> clamp.([11, 8, 5], 10, 6) # an example where lo > hi +3-element Vector{Int64}: + 6 + 6 + 10 +``` +""" +function clamp(x::X, lo::L, hi::H) where {X,L,H} + T = promote_type(X, L, H) + return (x > hi) ? convert(T, hi) : (x < lo) ? convert(T, lo) : convert(T, x) +end + +""" + clamp(x, T)::T + +Clamp `x` between `typemin(T)` and `typemax(T)` and convert the result to type `T`. + +See also [`trunc`](@ref). + +# Examples +```jldoctest +julia> clamp(200, Int8) +127 + +julia> clamp(-200, Int8) +-128 + +julia> trunc(Int, 4pi^2) +39 +``` +""" +function clamp(x, ::Type{T}) where {T<:Integer} + # delegating to clamp(x, typemin(T), typemax(T)) would promote types + # this way, we avoid unnecessary conversions + # think of, e.g., clamp(big(2) ^ 200, Int16) + lo = typemin(T) + hi = typemax(T) + return (x > hi) ? hi : (x < lo) ? lo : convert(T, x) +end + + +""" + clamp!(array::AbstractArray, lo, hi) + +Restrict values in `array` to the specified range, in-place. +See also [`clamp`](@ref). + +!!! compat "Julia 1.3" + `missing` entries in `array` require at least Julia 1.3. + +# Examples +```jldoctest +julia> row = collect(-4:4)'; + +julia> clamp!(row, 0, Inf) +1×9 adjoint(::Vector{Int64}) with eltype Int64: + 0 0 0 0 0 1 2 3 4 + +julia> clamp.((-4:4)', 0, Inf) +1×9 Matrix{Float64}: + 0.0 0.0 0.0 0.0 0.0 1.0 2.0 3.0 4.0 +``` +""" +function clamp!(x::AbstractArray, lo, hi) + @inbounds for i in eachindex(x) + x[i] = clamp(x[i], lo, hi) + end + x +end + +""" + clamp(x::Integer, r::AbstractUnitRange) + +Clamp `x` to lie within range `r`. + +!!! compat "Julia 1.6" + This method requires at least Julia 1.6. +""" +clamp(x::Integer, r::AbstractUnitRange{<:Integer}) = clamp(x, first(r), last(r)) diff --git a/base/io.jl b/base/io.jl index 0f1812942d23e..83a215d6359fc 100644 --- a/base/io.jl +++ b/base/io.jl @@ -543,8 +543,8 @@ julia> rm("my_file.txt") ``` """ readuntil(filename::AbstractString, delim; kw...) = open(io->readuntil(io, delim; kw...), convert(String, filename)::String) -readuntil(stream::IO, delim::UInt8; kw...) = _unsafe_take!(copyuntil(IOBuffer(sizehint=70), stream, delim; kw...)) -readuntil(stream::IO, delim::Union{AbstractChar, AbstractString}; kw...) = String(_unsafe_take!(copyuntil(IOBuffer(sizehint=70), stream, delim; kw...))) +readuntil(stream::IO, delim::UInt8; kw...) = _unsafe_take!(copyuntil(IOBuffer(sizehint=16), stream, delim; kw...)) +readuntil(stream::IO, delim::Union{AbstractChar, AbstractString}; kw...) = String(_unsafe_take!(copyuntil(IOBuffer(sizehint=16), stream, delim; kw...))) readuntil(stream::IO, delim::T; keep::Bool=false) where T = _copyuntil(Vector{T}(), stream, delim, keep) @@ -617,7 +617,7 @@ Logan readline(filename::AbstractString; keep::Bool=false) = open(io -> readline(io; keep), filename) readline(s::IO=stdin; keep::Bool=false) = - String(_unsafe_take!(copyline(IOBuffer(sizehint=70), s; keep))) + String(_unsafe_take!(copyline(IOBuffer(sizehint=16), s; keep))) """ copyline(out::IO, io::IO=stdin; keep::Bool=false) @@ -1111,7 +1111,7 @@ function copyuntil(out::IO, io::IO, target::AbstractString; keep::Bool=false) end function readuntil(io::IO, target::AbstractVector{T}; keep::Bool=false) where T - out = (T === UInt8 ? resize!(StringVector(70), 0) : Vector{T}()) + out = (T === UInt8 ? resize!(StringVector(16), 0) : Vector{T}()) readuntil_vector!(io, target, keep, out) return out end diff --git a/base/iobuffer.jl b/base/iobuffer.jl index 04a694a4fec15..c0c2731eec08b 100644 --- a/base/iobuffer.jl +++ b/base/iobuffer.jl @@ -42,7 +42,7 @@ end # allocate Vector{UInt8}s for IOBuffer storage that can efficiently become Strings StringMemory(n::Integer) = unsafe_wrap(Memory{UInt8}, _string_n(n)) -StringVector(n::Integer) = view(StringMemory(n), 1:n)::Vector{UInt8} +StringVector(n::Integer) = wrap(Array, StringMemory(n)) # IOBuffers behave like Files. They are typically readable and writable. They are seekable. (They can be appendable). @@ -466,7 +466,7 @@ function take!(io::IOBuffer) if nbytes == 0 || io.reinit data = StringVector(0) elseif io.writable - data = view(io.data, io.offset+1:nbytes+io.offset) + data = wrap(Array, memoryref(io.data, io.offset + 1), nbytes) else data = copyto!(StringVector(nbytes), 1, io.data, io.offset + 1, nbytes) end @@ -475,7 +475,7 @@ function take!(io::IOBuffer) if nbytes == 0 data = StringVector(0) elseif io.writable - data = view(io.data, io.ptr:io.ptr+nbytes-1) + data = wrap(Array, memoryref(io.data, io.ptr), nbytes) else data = read!(io, data) end @@ -501,7 +501,11 @@ state. This should only be used internally for performance-critical It might save an allocation compared to `take!` (if the compiler elides the Array allocation), as well as omits some checks. """ -_unsafe_take!(io::IOBuffer) = view(io.data, io.offset+1:io.size) +_unsafe_take!(io::IOBuffer) = + wrap(Array, io.size == io.offset ? + memoryref(Memory{UInt8}()) : + memoryref(io.data, io.offset + 1), + io.size - io.offset) function write(to::IO, from::GenericIOBuffer) written::Int = bytesavailable(from) diff --git a/base/loading.jl b/base/loading.jl index fa46819c5731c..4dc735f0099d8 100644 --- a/base/loading.jl +++ b/base/loading.jl @@ -822,14 +822,15 @@ end # given a project directory (implicit env from LOAD_PATH) and a name, # find an entry point for `name`, and see if it has an associated project file function entry_point_and_project_file(dir::String, name::String)::Union{Tuple{Nothing,Nothing},Tuple{String,Nothing},Tuple{String,String}} - path = normpath(joinpath(dir, "$name.jl")) - isfile_casesensitive(path) && return path, nothing dir_name = joinpath(dir, name) path, project_file = entry_point_and_project_file_inside(dir_name, name) path === nothing || return path, project_file dir_jl = dir_name * ".jl" path, project_file = entry_point_and_project_file_inside(dir_jl, name) path === nothing || return path, project_file + # check for less likely case with a bare file and no src directory last to minimize stat calls + path = normpath(joinpath(dir, "$name.jl")) + isfile_casesensitive(path) && return path, nothing return nothing, nothing end @@ -3046,7 +3047,9 @@ function compilecache(pkg::PkgId, path::String, internal_stderr::IO = stderr, in end end # this is atomic according to POSIX (not Win32): - rename(tmppath, cachefile; force=true) + # but force=true means it will fall back to non atomic + # move if the initial rename fails. + mv(tmppath, cachefile; force=true) return cachefile, ocachefile end finally @@ -3065,7 +3068,7 @@ end function rename_unique_ocachefile(tmppath_so::String, ocachefile_orig::String, ocachefile::String = ocachefile_orig, num = 0) try - rename(tmppath_so, ocachefile; force=true) + mv(tmppath_so, ocachefile; force=true) catch e e isa IOError || rethrow() # If `rm` was called on a dir containing a loaded DLL, we moved it to temp for cleanup @@ -3663,7 +3666,13 @@ end ignore_loaded::Bool=false, requested_flags::CacheFlags=CacheFlags(), reasons::Union{Dict{String,Int},Nothing}=nothing, stalecheck::Bool=true) # n.b.: this function does nearly all of the file validation, not just those checks related to stale, so the name is potentially unclear - io = open(cachefile, "r") + io = try + open(cachefile, "r") + catch ex + ex isa IOError || ex isa SystemError || rethrow() + @debug "Rejecting cache file $cachefile for $modkey because it could not be opened" isfile(cachefile) + return true + end try checksum = isvalid_cache_header(io) if iszero(checksum) @@ -3809,7 +3818,7 @@ end end if !ispath(f) _f = fixup_stdlib_path(f) - if isfile(_f) && startswith(_f, Sys.STDLIB) + if _f != f && isfile(_f) && startswith(_f, Sys.STDLIB) continue end @debug "Rejecting stale cache file $cachefile because file $f does not exist" @@ -3831,13 +3840,14 @@ end return true end else - fsize = filesize(f) + fstat = stat(f) + fsize = filesize(fstat) if fsize != fsize_req @debug "Rejecting stale cache file $cachefile because file size of $f has changed (file size $fsize, before $fsize_req)" record_reason(reasons, "include_dependency fsize change") return true end - hash = isdir(f) ? _crc32c(join(readdir(f))) : open(_crc32c, f, "r") + hash = isdir(fstat) ? _crc32c(join(readdir(f))) : open(_crc32c, f, "r") if hash != hash_req @debug "Rejecting stale cache file $cachefile because hash of $f has changed (hash $hash, before $hash_req)" record_reason(reasons, "include_dependency fhash change") diff --git a/base/lock.jl b/base/lock.jl index 7cbb023a78ee4..b69f3c5c03638 100644 --- a/base/lock.jl +++ b/base/lock.jl @@ -498,10 +498,10 @@ This provides an acquire & release memory ordering on notify/wait. The `autoreset` functionality and memory ordering guarantee requires at least Julia 1.8. """ mutable struct Event - const notify::ThreadSynchronizer + const notify::Threads.Condition const autoreset::Bool @atomic set::Bool - Event(autoreset::Bool=false) = new(ThreadSynchronizer(), autoreset, false) + Event(autoreset::Bool=false) = new(Threads.Condition(), autoreset, false) end function wait(e::Event) diff --git a/base/math.jl b/base/math.jl index de275a2afc048..da51ab3a17bd0 100644 --- a/base/math.jl +++ b/base/math.jl @@ -23,7 +23,7 @@ import .Base: log, exp, sin, cos, tan, sinh, cosh, tanh, asin, using .Base: sign_mask, exponent_mask, exponent_one, exponent_half, uinttype, significand_mask, significand_bits, exponent_bits, exponent_bias, - exponent_max, exponent_raw_max + exponent_max, exponent_raw_max, clamp, clamp! using Core.Intrinsics: sqrt_llvm @@ -69,104 +69,6 @@ end return Txy, T(xy-Txy) end -""" - clamp(x, lo, hi) - -Return `x` if `lo <= x <= hi`. If `x > hi`, return `hi`. If `x < lo`, return `lo`. Arguments -are promoted to a common type. - -See also [`clamp!`](@ref), [`min`](@ref), [`max`](@ref). - -!!! compat "Julia 1.3" - `missing` as the first argument requires at least Julia 1.3. - -# Examples -```jldoctest -julia> clamp.([pi, 1.0, big(10)], 2.0, 9.0) -3-element Vector{BigFloat}: - 3.141592653589793238462643383279502884197169399375105820974944592307816406286198 - 2.0 - 9.0 - -julia> clamp.([11, 8, 5], 10, 6) # an example where lo > hi -3-element Vector{Int64}: - 6 - 6 - 10 -``` -""" -function clamp(x::X, lo::L, hi::H) where {X,L,H} - T = promote_type(X, L, H) - return (x > hi) ? convert(T, hi) : (x < lo) ? convert(T, lo) : convert(T, x) -end - -""" - clamp(x, T)::T - -Clamp `x` between `typemin(T)` and `typemax(T)` and convert the result to type `T`. - -See also [`trunc`](@ref). - -# Examples -```jldoctest -julia> clamp(200, Int8) -127 - -julia> clamp(-200, Int8) --128 - -julia> trunc(Int, 4pi^2) -39 -``` -""" -function clamp(x, ::Type{T}) where {T<:Integer} - # delegating to clamp(x, typemin(T), typemax(T)) would promote types - # this way, we avoid unnecessary conversions - # think of, e.g., clamp(big(2) ^ 200, Int16) - lo = typemin(T) - hi = typemax(T) - return (x > hi) ? hi : (x < lo) ? lo : convert(T, x) -end - - -""" - clamp!(array::AbstractArray, lo, hi) - -Restrict values in `array` to the specified range, in-place. -See also [`clamp`](@ref). - -!!! compat "Julia 1.3" - `missing` entries in `array` require at least Julia 1.3. - -# Examples -```jldoctest -julia> row = collect(-4:4)'; - -julia> clamp!(row, 0, Inf) -1×9 adjoint(::Vector{Int64}) with eltype Int64: - 0 0 0 0 0 1 2 3 4 - -julia> clamp.((-4:4)', 0, Inf) -1×9 Matrix{Float64}: - 0.0 0.0 0.0 0.0 0.0 1.0 2.0 3.0 4.0 -``` -""" -function clamp!(x::AbstractArray, lo, hi) - @inbounds for i in eachindex(x) - x[i] = clamp(x[i], lo, hi) - end - x -end - -""" - clamp(x::Integer, r::AbstractUnitRange) - -Clamp `x` to lie within range `r`. - -!!! compat "Julia 1.6" - This method requires at least Julia 1.6. -""" -clamp(x::Integer, r::AbstractUnitRange{<:Integer}) = clamp(x, first(r), last(r)) """ evalpoly(x, p) @@ -1690,7 +1592,6 @@ end exp2(x::AbstractFloat) = 2^x exp10(x::AbstractFloat) = 10^x -clamp(::Missing, lo, hi) = missing fourthroot(::Missing) = missing end # module diff --git a/base/missing.jl b/base/missing.jl index ce174edc297e3..1f34195efed88 100644 --- a/base/missing.jl +++ b/base/missing.jl @@ -135,6 +135,7 @@ min(::Any, ::Missing) = missing max(::Missing, ::Missing) = missing max(::Missing, ::Any) = missing max(::Any, ::Missing) = missing +clamp(::Missing, lo, hi) = missing missing_conversion_msg(@nospecialize T) = LazyString("cannot convert a missing value to type ", T, ": use Union{", T, ", Missing} instead") diff --git a/base/multidimensional.jl b/base/multidimensional.jl index bd3641db4999c..5e32a19c2cafb 100644 --- a/base/multidimensional.jl +++ b/base/multidimensional.jl @@ -1669,11 +1669,10 @@ function permutedims(B::StridedArray, perm) permutedims!(P, B, perm) end -function checkdims_perm(P::AbstractArray{TP,N}, B::AbstractArray{TB,N}, perm) where {TP,TB,N} - indsB = axes(B) - length(perm) == N || throw(ArgumentError("expected permutation of size $N, but length(perm)=$(length(perm))")) +checkdims_perm(P::AbstractArray{TP,N}, B::AbstractArray{TB,N}, perm) where {TP,TB,N} = checkdims_perm(axes(P), axes(B), perm) +function checkdims_perm(indsP::NTuple{N, AbstractUnitRange}, indsB::NTuple{N, AbstractUnitRange}, perm) where {N} + length(perm) == N || throw(ArgumentError(LazyString("expected permutation of size ", N, ", but length(perm)=", length(perm)))) isperm(perm) || throw(ArgumentError("input is not a permutation")) - indsP = axes(P) for i in eachindex(perm) indsP[i] == indsB[perm[i]] || throw(DimensionMismatch("destination tensor of incorrect size")) end @@ -1683,7 +1682,7 @@ end for (V, PT, BT) in Any[((:N,), BitArray, BitArray), ((:T,:N), Array, StridedArray)] @eval @generated function permutedims!(P::$PT{$(V...)}, B::$BT{$(V...)}, perm) where $(V...) quote - checkdims_perm(P, B, perm) + checkdims_perm(axes(P), axes(B), perm) #calculates all the strides native_strides = size_to_strides(1, size(B)...) diff --git a/base/namedtuple.jl b/base/namedtuple.jl index 98192480db9dd..e316dbd37ccf5 100644 --- a/base/namedtuple.jl +++ b/base/namedtuple.jl @@ -424,6 +424,24 @@ function diff_fallback(a::NamedTuple, an::Tuple{Vararg{Symbol}}, bn::Tuple{Varar _new_NamedTuple(NamedTuple{names, types}, (A...,)) end +""" + delete(a::NamedTuple, field::Symbol) + +Construct a new named tuple from `a` by removing the named field. + +```jldoctest +julia> Base.delete((a=1, b=2, c=3), :a) +(b = 2, c = 3) + +julia> Base.delete((a=1, b=2, c=3), :b) +(a = 1, c = 3) +``` +""" +@constprop :aggressive function delete(a::NamedTuple{an}, field::Symbol) where {an} + names = diff_names(an, (field,)) + NamedTuple{names}(a) +end + """ structdiff(a::NamedTuple, b::Union{NamedTuple,Type{NamedTuple}}) diff --git a/base/operators.jl b/base/operators.jl index 4a9daf21c4be5..2c8070b44d704 100644 --- a/base/operators.jl +++ b/base/operators.jl @@ -58,12 +58,14 @@ but which do not execute the operator or return a Bool: """ (<:) +import Core: >: + """ >:(T1, T2) Supertype operator, equivalent to `T2 <: T1`. """ -(>:)(@nospecialize(a), @nospecialize(b)) = (b <: a) +>: """ supertype(T::Union{DataType, UnionAll}) @@ -111,9 +113,10 @@ Use [`isequal`](@ref) or [`===`](@ref) to always get a `Bool` result. New numeric types should implement this function for two arguments of the new type, and handle comparison to other types via promotion rules where possible. -[`isequal`](@ref) falls back to `==`, so new methods of `==` will be used by the -[`Dict`](@ref) type to compare keys. If your type will be used as a dictionary key, it -should therefore also implement [`hash`](@ref). +Equality and hashing are intimately related; two values that are considered [`isequal`](@ref) **must** +have the same [`hash`](@ref) and by default `isequal` falls back to `==`. If a type customizes the behavior of `==` and/or [`isequal`](@ref), +then [`hash`](@ref) must be similarly implemented to ensure `isequal` and `hash` agree. `Set`s, `Dict`s, and many other internal +implementations assume that this invariant holds. If some type defines `==`, [`isequal`](@ref), and [`isless`](@ref) then it should also implement [`<`](@ref) to ensure consistency of comparisons. @@ -345,6 +348,7 @@ true === const ≡ = === +import Core: !== """ !==(x, y) ≢(x,y) @@ -362,7 +366,8 @@ julia> a ≢ a false ``` """ -!==(@nospecialize(x), @nospecialize(y)) = !(x === y) +!== + const ≢ = !== """ @@ -1149,40 +1154,55 @@ julia> filter(!isletter, str) !(f::ComposedFunction{typeof(!)}) = f.inner #allows !!f === f """ - Fix1(f, x) + Fix{N}(f, x) -A type representing a partially-applied version of the two-argument function -`f`, with the first argument fixed to the value "x". In other words, -`Fix1(f, x)` behaves similarly to `y->f(x, y)`. +A type representing a partially-applied version of a function `f`, with the argument +`x` fixed at position `N::Int`. In other words, `Fix{3}(f, x)` behaves similarly to +`(y1, y2, y3...; kws...) -> f(y1, y2, x, y3...; kws...)`. -See also [`Fix2`](@ref Base.Fix2). +!!! compat "Julia 1.12" + This general functionality requires at least Julia 1.12, while `Fix1` and `Fix2` + are available earlier. + +!!! note + When nesting multiple `Fix`, note that the `N` in `Fix{N}` is _relative_ to the current + available arguments, rather than an absolute ordering on the target function. For example, + `Fix{1}(Fix{2}(f, 4), 4)` fixes the first and second arg, while `Fix{2}(Fix{1}(f, 4), 4)` + fixes the first and third arg. """ -struct Fix1{F,T} <: Function +struct Fix{N,F,T} <: Function f::F x::T - Fix1(f::F, x) where {F} = new{F,_stable_typeof(x)}(f, x) - Fix1(f::Type{F}, x) where {F} = new{Type{F},_stable_typeof(x)}(f, x) + function Fix{N}(f::F, x) where {N,F} + if !(N isa Int) + throw(ArgumentError(LazyString("expected type parameter in `Fix` to be `Int`, but got `", N, "::", typeof(N), "`"))) + elseif N < 1 + throw(ArgumentError(LazyString("expected `N` in `Fix{N}` to be integer greater than 0, but got ", N))) + end + new{N,_stable_typeof(f),_stable_typeof(x)}(f, x) + end +end + +function (f::Fix{N})(args::Vararg{Any,M}; kws...) where {N,M} + M < N-1 && throw(ArgumentError(LazyString("expected at least ", N-1, " arguments to `Fix{", N, "}`, but got ", M))) + return f.f(args[begin:begin+(N-2)]..., f.x, args[begin+(N-1):end]...; kws...) end -(f::Fix1)(y) = f.f(f.x, y) +# Special cases for improved constant propagation +(f::Fix{1})(arg; kws...) = f.f(f.x, arg; kws...) +(f::Fix{2})(arg; kws...) = f.f(arg, f.x; kws...) """ - Fix2(f, x) - -A type representing a partially-applied version of the two-argument function -`f`, with the second argument fixed to the value "x". In other words, -`Fix2(f, x)` behaves similarly to `y->f(y, x)`. +Alias for `Fix{1}`. See [`Fix`](@ref Base.Fix). """ -struct Fix2{F,T} <: Function - f::F - x::T +const Fix1{F,T} = Fix{1,F,T} - Fix2(f::F, x) where {F} = new{F,_stable_typeof(x)}(f, x) - Fix2(f::Type{F}, x) where {F} = new{Type{F},_stable_typeof(x)}(f, x) -end +""" +Alias for `Fix{2}`. See [`Fix`](@ref Base.Fix). +""" +const Fix2{F,T} = Fix{2,F,T} -(f::Fix2)(y) = f.f(y, f.x) """ isequal(x) diff --git a/base/permuteddimsarray.jl b/base/permuteddimsarray.jl index 4e77d6b13ce21..cf9748168aac2 100644 --- a/base/permuteddimsarray.jl +++ b/base/permuteddimsarray.jl @@ -282,7 +282,7 @@ regions. See also [`permutedims`](@ref). """ function permutedims!(dest, src::AbstractArray, perm) - Base.checkdims_perm(dest, src, perm) + Base.checkdims_perm(axes(dest), axes(src), perm) P = PermutedDimsArray(dest, invperm(perm)) _copy!(P, src) return dest diff --git a/base/precompilation.jl b/base/precompilation.jl index dfaf671a63534..aa70718eab9bc 100644 --- a/base/precompilation.jl +++ b/base/precompilation.jl @@ -710,7 +710,7 @@ function precompilepkgs(pkgs::Vector{String}=String[]; while !printloop_should_exit lock(print_lock) do term_size = Base.displaysize(io)::Tuple{Int,Int} - num_deps_show = term_size[1] - 3 + num_deps_show = max(term_size[1] - 3, 2) # show at least 2 deps pkg_queue_show = if !interrupted_or_done.set && length(pkg_queue) > num_deps_show last(pkg_queue, num_deps_show) else @@ -897,6 +897,7 @@ function precompilepkgs(pkgs::Vector{String}=String[]; length(tasks) == 1 && notify(interrupted_or_done) end end + Base.errormonitor(task) # interrupts are handled separately so ok to watch for other errors like this push!(tasks, task) end end diff --git a/base/public.jl b/base/public.jl index c11c76c13053c..862aff48da63e 100644 --- a/base/public.jl +++ b/base/public.jl @@ -14,6 +14,7 @@ public AsyncCondition, CodeUnits, Event, + Fix, Fix1, Fix2, Generator, diff --git a/base/reduce.jl b/base/reduce.jl index bbfd66e5686ed..0c37256b64fb5 100644 --- a/base/reduce.jl +++ b/base/reduce.jl @@ -638,11 +638,11 @@ function mapreduce_impl(f, op::Union{typeof(max), typeof(min)}, start = first + 1 simdstop = start + chunk_len - 4 while simdstop <= last - 3 - @inbounds for i in start:4:simdstop - v1 = _fast(op, v1, f(A[i+0])) - v2 = _fast(op, v2, f(A[i+1])) - v3 = _fast(op, v3, f(A[i+2])) - v4 = _fast(op, v4, f(A[i+3])) + for i in start:4:simdstop + v1 = _fast(op, v1, f(@inbounds(A[i+0]))) + v2 = _fast(op, v2, f(@inbounds(A[i+1]))) + v3 = _fast(op, v3, f(@inbounds(A[i+2]))) + v4 = _fast(op, v4, f(@inbounds(A[i+3]))) end checkbounds(A, simdstop+3) start += chunk_len diff --git a/base/reducedim.jl b/base/reducedim.jl index 1d74fb0d498a5..e74fe2b765277 100644 --- a/base/reducedim.jl +++ b/base/reducedim.jl @@ -196,11 +196,8 @@ end ## generic (map)reduction -has_fast_linear_indexing(a::AbstractArrayOrBroadcasted) = false -has_fast_linear_indexing(a::Array) = true -has_fast_linear_indexing(::Union{Number,Ref,AbstractChar}) = true # 0d objects, for Broadcasted -has_fast_linear_indexing(bc::Broadcast.Broadcasted) = - all(has_fast_linear_indexing, bc.args) +has_fast_linear_indexing(a::AbstractArrayOrBroadcasted) = IndexStyle(a) === IndexLinear() +has_fast_linear_indexing(a::AbstractVector) = true function check_reducedims(R, A) # Check whether R has compatible dimensions w.r.t. A for reduction @@ -272,19 +269,20 @@ function _mapreducedim!(f, op, R::AbstractArray, A::AbstractArrayOrBroadcasted) if reducedim1(R, A) # keep the accumulator as a local variable when reducing along the first dimension i1 = first(axes1(R)) - @inbounds for IA in CartesianIndices(indsAt) + for IA in CartesianIndices(indsAt) IR = Broadcast.newindex(IA, keep, Idefault) - r = R[i1,IR] + @inbounds r = R[i1,IR] @simd for i in axes(A, 1) - r = op(r, f(A[i, IA])) + r = op(r, f(@inbounds(A[i, IA]))) end - R[i1,IR] = r + @inbounds R[i1,IR] = r end else - @inbounds for IA in CartesianIndices(indsAt) + for IA in CartesianIndices(indsAt) IR = Broadcast.newindex(IA, keep, Idefault) @simd for i in axes(A, 1) - R[i,IR] = op(R[i,IR], f(A[i,IA])) + v = op(@inbounds(R[i,IR]), f(@inbounds(A[i,IA]))) + @inbounds R[i,IR] = v end end end @@ -1028,33 +1026,33 @@ function findminmax!(f, op, Rval, Rind, A::AbstractArray{T,N}) where {T,N} zi = zero(eltype(ks)) if reducedim1(Rval, A) i1 = first(axes1(Rval)) - @inbounds for IA in CartesianIndices(indsAt) + for IA in CartesianIndices(indsAt) IR = Broadcast.newindex(IA, keep, Idefault) - tmpRv = Rval[i1,IR] - tmpRi = Rind[i1,IR] + @inbounds tmpRv = Rval[i1,IR] + @inbounds tmpRi = Rind[i1,IR] for i in axes(A,1) k, kss = y::Tuple - tmpAv = f(A[i,IA]) + tmpAv = f(@inbounds(A[i,IA])) if tmpRi == zi || op(tmpRv, tmpAv) tmpRv = tmpAv tmpRi = k end y = iterate(ks, kss) end - Rval[i1,IR] = tmpRv - Rind[i1,IR] = tmpRi + @inbounds Rval[i1,IR] = tmpRv + @inbounds Rind[i1,IR] = tmpRi end else - @inbounds for IA in CartesianIndices(indsAt) + for IA in CartesianIndices(indsAt) IR = Broadcast.newindex(IA, keep, Idefault) for i in axes(A, 1) k, kss = y::Tuple - tmpAv = f(A[i,IA]) - tmpRv = Rval[i,IR] - tmpRi = Rind[i,IR] + tmpAv = f(@inbounds(A[i,IA])) + @inbounds tmpRv = Rval[i,IR] + @inbounds tmpRi = Rind[i,IR] if tmpRi == zi || op(tmpRv, tmpAv) - Rval[i,IR] = tmpAv - Rind[i,IR] = k + @inbounds Rval[i,IR] = tmpAv + @inbounds Rind[i,IR] = k end y = iterate(ks, kss) end diff --git a/base/reflection.jl b/base/reflection.jl index 7f9772e5ec976..6dfaf34bc0047 100644 --- a/base/reflection.jl +++ b/base/reflection.jl @@ -212,6 +212,8 @@ end Get the name of field `i` of a `DataType`. +The return type is `Symbol`, except when `x <: Tuple`, in which case the index of the field is returned, of type `Int`. + # Examples ```jldoctest julia> fieldname(Rational, 1) @@ -219,6 +221,9 @@ julia> fieldname(Rational, 1) julia> fieldname(Rational, 2) :den + +julia> fieldname(Tuple{String,Int}, 2) +2 ``` """ function fieldname(t::DataType, i::Integer) @@ -246,6 +251,9 @@ fieldname(t::Type{<:Tuple}, i::Integer) = Get a tuple with the names of the fields of a `DataType`. +Each name is a `Symbol`, except when `x <: Tuple`, in which case each name (actually the +index of the field) is an `Int`. + See also [`propertynames`](@ref), [`hasfield`](@ref). # Examples @@ -255,6 +263,9 @@ julia> fieldnames(Rational) julia> fieldnames(typeof(1+im)) (:re, :im) + +julia> fieldnames(Tuple{String,Int}) +(1, 2) ``` """ fieldnames(t::DataType) = (fieldcount(t); # error check to make sure type is specific enough diff --git a/base/reinterpretarray.jl b/base/reinterpretarray.jl index d74a043293a3a..d31f3ebb5dd2d 100644 --- a/base/reinterpretarray.jl +++ b/base/reinterpretarray.jl @@ -373,6 +373,7 @@ has_offset_axes(a::ReinterpretArray) = has_offset_axes(a.parent) elsize(::Type{<:ReinterpretArray{T}}) where {T} = sizeof(T) cconvert(::Type{Ptr{T}}, a::ReinterpretArray{T,N,S} where N) where {T,S} = cconvert(Ptr{S}, a.parent) +unsafe_convert(::Type{Ptr{T}}, a::ReinterpretArray{T,N,S} where N) where {T,S} = Ptr{T}(unsafe_convert(Ptr{S},a.parent)) @propagate_inbounds function getindex(a::NonReshapedReinterpretArray{T,0,S}) where {T,S} if isprimitivetype(T) && isprimitivetype(S) diff --git a/base/reshapedarray.jl b/base/reshapedarray.jl index 4173ef1d3f598..019f1d30a25c2 100644 --- a/base/reshapedarray.jl +++ b/base/reshapedarray.jl @@ -324,6 +324,7 @@ setindex!(A::ReshapedRange, val, index::ReshapedIndex) = _rs_setindex!_err() @noinline _rs_setindex!_err() = error("indexed assignment fails for a reshaped range; consider calling collect") cconvert(::Type{Ptr{T}}, a::ReshapedArray{T}) where {T} = cconvert(Ptr{T}, parent(a)) +unsafe_convert(::Type{Ptr{T}}, a::ReshapedArray{T}) where {T} = unsafe_convert(Ptr{T}, a.parent) # Add a few handy specializations to further speed up views of reshaped ranges const ReshapedUnitRange{T,N,A<:AbstractUnitRange} = ReshapedArray{T,N,A,Tuple{}} diff --git a/base/show.jl b/base/show.jl index c1ad45af5cc83..fa66a198aef4d 100644 --- a/base/show.jl +++ b/base/show.jl @@ -1407,11 +1407,11 @@ function show_delim_array(io::IO, itr::Union{AbstractArray,SimpleVector}, op, de x = itr[i] show(recur_io, x) end - i += 1 - if i > l + if i == l delim_one && first && print(io, delim) break end + i += 1 first = false print(io, delim) print(io, ' ') diff --git a/base/stat.jl b/base/stat.jl index 29edf010b7815..3330ff0c35bc8 100644 --- a/base/stat.jl +++ b/base/stat.jl @@ -184,8 +184,14 @@ macro stat_call(sym, arg1type, arg) end stat(fd::OS_HANDLE) = @stat_call jl_fstat OS_HANDLE fd -stat(path::AbstractString) = @stat_call jl_stat Cstring path -lstat(path::AbstractString) = @stat_call jl_lstat Cstring path +function stat(path::AbstractString) + # @info "stat($(repr(path)))" exception=(ErrorException("Fake error for backtrace printing"),stacktrace()) + @stat_call jl_stat Cstring path +end +function lstat(path::AbstractString) + # @info "lstat($(repr(path)))" exception=(ErrorException("Fake error for backtrace printing"),stacktrace()) + @stat_call jl_lstat Cstring path +end if RawFD !== OS_HANDLE global stat(fd::RawFD) = stat(Libc._get_osfhandle(fd)) end diff --git a/base/strings/io.jl b/base/strings/io.jl index 46353ff6f7c29..acbd945c8e137 100644 --- a/base/strings/io.jl +++ b/base/strings/io.jl @@ -246,7 +246,7 @@ end # optimized methods to avoid iterating over chars write(io::IO, s::Union{String,SubString{String}}) = - GC.@preserve s Int(unsafe_write(io, pointer(s), reinterpret(UInt, sizeof(s))))::Int + GC.@preserve s (unsafe_write(io, pointer(s), reinterpret(UInt, sizeof(s))) % Int)::Int print(io::IO, s::Union{String,SubString{String}}) = (write(io, s); nothing) """ @@ -354,7 +354,8 @@ function join(io::IO, iterator, delim="") end function _join_preserve_annotations(iterator, args...) - if isconcretetype(eltype(iterator)) && !_isannotated(eltype(iterator)) && !any(_isannotated, args) + et = @default_eltype(iterator) + if isconcretetype(et) && !_isannotated(et) && !any(_isannotated, args) sprint(join, iterator, args...) else io = AnnotatedIOBuffer() @@ -363,7 +364,7 @@ function _join_preserve_annotations(iterator, args...) # of iterators with a non-concrete eltype), that the result is annotated # in nature, we extract an `AnnotatedString`, otherwise we just extract # a plain `String` from `io`. - if isconcretetype(eltype(iterator)) || !isempty(io.annotations) + if isconcretetype(et) || !isempty(io.annotations) read(seekstart(io), AnnotatedString{String}) else String(take!(io.io)) @@ -382,8 +383,8 @@ escape_nul(c::Union{Nothing, AbstractChar}) = (c !== nothing && '0' <= c <= '7') ? "\\x00" : "\\0" """ - escape_string(str::AbstractString[, esc]; keep = ())::AbstractString - escape_string(io, str::AbstractString[, esc]; keep = ())::Nothing + escape_string(str::AbstractString[, esc]; keep=(), ascii=false, fullhex=false)::AbstractString + escape_string(io, str::AbstractString[, esc]; keep=())::Nothing General escaping of traditional C and Unicode escape sequences. The first form returns the escaped string, the second prints the result to `io`. @@ -398,11 +399,23 @@ escaped by a prepending backslash (`\"` is also escaped by default in the first The argument `keep` specifies a collection of characters which are to be kept as they are. Notice that `esc` has precedence here. +The argument `ascii` can be set to `true` to escape all non-ASCII characters, +whereas the default `ascii=false` outputs printable Unicode characters as-is. +(`keep` takes precedence over `ascii`.) + +The argument `fullhex` can be set to `true` to require all `\\u` escapes to be +printed with 4 hex digits, and `\\U` escapes to be printed with 8 hex digits, +whereas by default (`fullhex=false`) they are printed with fewer digits if +possible (omitting leading zeros). + See also [`unescape_string`](@ref) for the reverse operation. !!! compat "Julia 1.7" The `keep` argument is available as of Julia 1.7. +!!! compat "Julia 1.12" + The `ascii` and `fullhex` arguments require Julia 1.12. + # Examples ```jldoctest julia> escape_string("aaa\\nbbb") @@ -421,7 +434,7 @@ julia> escape_string(string('\\u2135','\\0','0')) # \\0 would be ambiguous "ℵ\\\\x000" ``` """ -function escape_string(io::IO, s::AbstractString, esc=""; keep = ()) +function escape_string(io::IO, s::AbstractString, esc=""; keep = (), ascii::Bool=false, fullhex::Bool=false) a = Iterators.Stateful(s) for c::AbstractChar in a if c in esc @@ -436,10 +449,10 @@ function escape_string(io::IO, s::AbstractString, esc=""; keep = ()) isprint(c) ? print(io, c) : print(io, "\\x", string(UInt32(c), base = 16, pad = 2)) elseif !isoverlong(c) && !ismalformed(c) - isprint(c) ? print(io, c) : - c <= '\x7f' ? print(io, "\\x", string(UInt32(c), base = 16, pad = 2)) : - c <= '\uffff' ? print(io, "\\u", string(UInt32(c), base = 16, pad = need_full_hex(peek(a)::Union{AbstractChar,Nothing}) ? 4 : 2)) : - print(io, "\\U", string(UInt32(c), base = 16, pad = need_full_hex(peek(a)::Union{AbstractChar,Nothing}) ? 8 : 4)) + !ascii && isprint(c) ? print(io, c) : + c <= '\x7f' ? print(io, "\\x", string(UInt32(c), base = 16, pad = 2)) : + c <= '\uffff' ? print(io, "\\u", string(UInt32(c), base = 16, pad = fullhex || need_full_hex(peek(a)::Union{AbstractChar,Nothing}) ? 4 : 2)) : + print(io, "\\U", string(UInt32(c), base = 16, pad = fullhex || need_full_hex(peek(a)::Union{AbstractChar,Nothing}) ? 8 : 4)) else # malformed or overlong u = bswap(reinterpret(UInt32, c)::UInt32) while true @@ -450,8 +463,8 @@ function escape_string(io::IO, s::AbstractString, esc=""; keep = ()) end end -escape_string(s::AbstractString, esc=('\"',); keep = ()) = - sprint((io)->escape_string(io, s, esc; keep = keep), sizehint=lastindex(s)) +escape_string(s::AbstractString, esc=('\"',); keep = (), ascii::Bool=false, fullhex::Bool=false) = + sprint((io)->escape_string(io, s, esc; keep, ascii, fullhex), sizehint=lastindex(s)) function print_quoted(io, s::AbstractString) print(io, '"') diff --git a/base/strings/string.jl b/base/strings/string.jl index 7917f463771b2..89e2ff288c3d7 100644 --- a/base/strings/string.jl +++ b/base/strings/string.jl @@ -115,10 +115,7 @@ String(s::AbstractString) = print_to_string(s) @assume_effects :total String(s::Symbol) = unsafe_string(unsafe_convert(Ptr{UInt8}, s)) unsafe_wrap(::Type{Memory{UInt8}}, s::String) = ccall(:jl_string_to_genericmemory, Ref{Memory{UInt8}}, (Any,), s) -function unsafe_wrap(::Type{Vector{UInt8}}, s::String) - mem = unsafe_wrap(Memory{UInt8}, s) - view(mem, eachindex(mem)) -end +unsafe_wrap(::Type{Vector{UInt8}}, s::String) = wrap(Array, unsafe_wrap(Memory{UInt8}, s)) Vector{UInt8}(s::CodeUnits{UInt8,String}) = copyto!(Vector{UInt8}(undef, length(s)), s) Vector{UInt8}(s::String) = Vector{UInt8}(codeunits(s)) diff --git a/base/strings/unicode.jl b/base/strings/unicode.jl index 42a4106d0f52f..3c6710025077c 100644 --- a/base/strings/unicode.jl +++ b/base/strings/unicode.jl @@ -256,6 +256,15 @@ julia> textwidth('⛵') ``` """ function textwidth(c::AbstractChar) + ismalformed(c) && return 1 + i = codepoint(c) + i < 0x7f && return Int(i >= 0x20) # ASCII fast path + Int(ccall(:utf8proc_charwidth, Cint, (UInt32,), i)) +end + +function textwidth(c::Char) + b = bswap(reinterpret(UInt32, c)) # from isascii(c) + b < 0x7f && return Int(b >= 0x20) # ASCII fast path ismalformed(c) && return 1 Int(ccall(:utf8proc_charwidth, Cint, (UInt32,), c)) end diff --git a/base/strings/util.jl b/base/strings/util.jl index 4b701001a8676..0ba76e1c76fa0 100644 --- a/base/strings/util.jl +++ b/base/strings/util.jl @@ -513,6 +513,154 @@ function rpad( r == 0 ? stringfn(s, p^q) : stringfn(s, p^q, first(p, r)) end +""" + rtruncate(str::AbstractString, maxwidth::Integer, replacement::Union{AbstractString,AbstractChar} = '…') + +Truncate `str` to at most `maxwidth` columns (as estimated by [`textwidth`](@ref)), replacing the last characters +with `replacement` if necessary. The default replacement string is "…". + +# Examples +```jldoctest +julia> s = rtruncate("🍕🍕 I love 🍕", 10) +"🍕🍕 I lo…" + +julia> textwidth(s) +10 + +julia> rtruncate("foo", 3) +"foo" +``` + +!!! compat "Julia 1.12" + This function was added in Julia 1.12. + +See also [`ltruncate`](@ref) and [`ctruncate`](@ref). +""" +function rtruncate(str::AbstractString, maxwidth::Integer, replacement::Union{AbstractString,AbstractChar} = '…') + ret = string_truncate_boundaries(str, Int(maxwidth), replacement, Val(:right)) + if isnothing(ret) + return string(str) + else + left, _ = ret::Tuple{Int,Int} + @views return str[begin:left] * replacement + end +end + +""" + ltruncate(str::AbstractString, maxwidth::Integer, replacement::Union{AbstractString,AbstractChar} = '…') + +Truncate `str` to at most `maxwidth` columns (as estimated by [`textwidth`](@ref)), replacing the first characters +with `replacement` if necessary. The default replacement string is "…". + +# Examples +```jldoctest +julia> s = ltruncate("🍕🍕 I love 🍕", 10) +"…I love 🍕" + +julia> textwidth(s) +10 + +julia> ltruncate("foo", 3) +"foo" +``` + +!!! compat "Julia 1.12" + This function was added in Julia 1.12. + +See also [`rtruncate`](@ref) and [`ctruncate`](@ref). +""" +function ltruncate(str::AbstractString, maxwidth::Integer, replacement::Union{AbstractString,AbstractChar} = '…') + ret = string_truncate_boundaries(str, Int(maxwidth), replacement, Val(:left)) + if isnothing(ret) + return string(str) + else + _, right = ret::Tuple{Int,Int} + @views return replacement * str[right:end] + end +end + +""" + ctruncate(str::AbstractString, maxwidth::Integer, replacement::Union{AbstractString,AbstractChar} = '…'; prefer_left::Bool = true) + +Truncate `str` to at most `maxwidth` columns (as estimated by [`textwidth`](@ref)), replacing the middle characters +with `replacement` if necessary. The default replacement string is "…". By default, the truncation +prefers keeping chars on the left, but this can be changed by setting `prefer_left` to `false`. + +# Examples +```jldoctest +julia> s = ctruncate("🍕🍕 I love 🍕", 10) +"🍕🍕 …e 🍕" + +julia> textwidth(s) +10 + +julia> ctruncate("foo", 3) +"foo" +``` + +!!! compat "Julia 1.12" + This function was added in Julia 1.12. + +See also [`ltruncate`](@ref) and [`rtruncate`](@ref). +""" +function ctruncate(str::AbstractString, maxwidth::Integer, replacement::Union{AbstractString,AbstractChar} = '…'; prefer_left::Bool = true) + ret = string_truncate_boundaries(str, Int(maxwidth), replacement, Val(:center), prefer_left) + if isnothing(ret) + return string(str) + else + left, right = ret::Tuple{Int,Int} + @views return str[begin:left] * replacement * str[right:end] + end +end + +function string_truncate_boundaries( + str::AbstractString, + maxwidth::Integer, + replacement::Union{AbstractString,AbstractChar}, + ::Val{mode}, + prefer_left::Bool = true) where {mode} + + maxwidth >= 0 || throw(ArgumentError("maxwidth $maxwidth should be non-negative")) + + # check efficiently for early return if str is less wide than maxwidth + total_width = 0 + for c in str + total_width += textwidth(c) + total_width > maxwidth && break + end + total_width <= maxwidth && return nothing + + l0, _ = left, right = firstindex(str), lastindex(str) + width = textwidth(replacement) + # used to balance the truncated width on either side + rm_width_left, rm_width_right, force_other = 0, 0, false + @inbounds while true + if mode === :left || (mode === :center && (!prefer_left || left > l0)) + rm_width = textwidth(str[right]) + if mode === :left || (rm_width_right <= rm_width_left || force_other) + force_other = false + (width += rm_width) <= maxwidth || break + rm_width_right += rm_width + right = prevind(str, right) + else + force_other = true + end + end + if mode ∈ (:right, :center) + rm_width = textwidth(str[left]) + if mode === :left || (rm_width_left <= rm_width_right || force_other) + force_other = false + (width += textwidth(str[left])) <= maxwidth || break + rm_width_left += rm_width + left = nextind(str, left) + else + force_other = true + end + end + end + return prevind(str, left), nextind(str, right) +end + """ eachsplit(str::AbstractString, dlm; limit::Integer=0, keepempty::Bool=true) eachsplit(str::AbstractString; limit::Integer=0, keepempty::Bool=false) diff --git a/base/sysinfo.jl b/base/sysinfo.jl index 3cb95396502a9..d0dcac8c6d416 100644 --- a/base/sysinfo.jl +++ b/base/sysinfo.jl @@ -165,7 +165,7 @@ end # without pulling in anything unnecessary like `CPU_NAME` function __init_build() global BINDIR = ccall(:jl_get_julia_bindir, Any, ())::String - vers = "v$(VERSION.major).$(VERSION.minor)" + vers = "v$(string(VERSION.major)).$(string(VERSION.minor))" global STDLIB = abspath(BINDIR, "..", "share", "julia", "stdlib", vers) nothing end diff --git a/base/task.jl b/base/task.jl index 4f7b1ea979a94..ae99a71585c85 100644 --- a/base/task.jl +++ b/base/task.jl @@ -813,6 +813,14 @@ macro sync_add(expr) end end +throwto_repl_task(@nospecialize val) = throwto(getfield(active_repl_backend, :backend_task)::Task, val) + +function is_repl_running() + return isdefined(Base, :active_repl_backend) && + (getfield(active_repl_backend, :backend_task)::Task)._state === task_state_runnable && + getfield(active_repl_backend, :in_eval) +end + # runtime system hook called when a task finishes function task_done_hook(t::Task) # `finish_task` sets `sigatomic` before entering this function @@ -834,10 +842,8 @@ function task_done_hook(t::Task) end if err && !handled && Threads.threadid() == 1 - if isa(result, InterruptException) && active_repl_backend !== nothing && - active_repl_backend.backend_task._state === task_state_runnable && isempty(Workqueue) && - active_repl_backend.in_eval - throwto(active_repl_backend.backend_task, result) # this terminates the task + if isa(result, InterruptException) && isempty(Workqueue) && is_repl_running() + throwto_repl_task(result) end end # Clear sigatomic before waiting @@ -848,11 +854,8 @@ function task_done_hook(t::Task) # If an InterruptException happens while blocked in the event loop, try handing # the exception to the REPL task since the current task is done. # issue #19467 - if Threads.threadid() == 1 && - isa(e, InterruptException) && active_repl_backend !== nothing && - active_repl_backend.backend_task._state === task_state_runnable && isempty(Workqueue) && - active_repl_backend.in_eval - throwto(active_repl_backend.backend_task, e) + if Threads.threadid() == 1 && isa(e, InterruptException) && isempty(Workqueue) && is_repl_running() + throwto_repl_task(e) else rethrow() end diff --git a/base/terminfo.jl b/base/terminfo.jl index 6f1d1ca8015f0..79713f4a86aa3 100644 --- a/base/terminfo.jl +++ b/base/terminfo.jl @@ -245,7 +245,8 @@ end Locate the terminfo file for `term`, return `nothing` if none could be found. The lookup policy is described in `terminfo(5)` "Fetching Compiled -Descriptions". +Descriptions". A terminfo database is included by default with Julia and is +taken to be the first entry of `@TERMINFO_DIRS@`. """ function find_terminfo_file(term::String) isempty(term) && return @@ -261,6 +262,7 @@ function find_terminfo_file(term::String) append!(terminfo_dirs, replace(split(ENV["TERMINFO_DIRS"], ':'), "" => "/usr/share/terminfo")) + push!(terminfo_dirs, normpath(Sys.BINDIR, DATAROOTDIR, "terminfo")) Sys.isunix() && push!(terminfo_dirs, "/etc/terminfo", "/lib/terminfo", "/usr/share/terminfo") for dir in terminfo_dirs @@ -268,8 +270,15 @@ function find_terminfo_file(term::String) return joinpath(dir, chr, term) elseif isfile(joinpath(dir, chrcode, term)) return joinpath(dir, chrcode, term) + elseif isfile(joinpath(dir, lowercase(chr), lowercase(term))) + # The vendored terminfo database is fully lowercase to avoid issues on + # case-sensitive filesystems. On Unix-like systems, terminfo files with + # different cases are hard links to one another, so this is still + # correct for non-vendored terminfo, just redundant. + return joinpath(dir, lowercase(chr), lowercase(term)) end end + return nothing end """ diff --git a/base/threadingconstructs.jl b/base/threadingconstructs.jl index 479bcd80c586d..a21d708b4a077 100644 --- a/base/threadingconstructs.jl +++ b/base/threadingconstructs.jl @@ -4,10 +4,10 @@ export threadid, nthreads, @threads, @spawn, threadpool, nthreadpools """ - Threads.threadid() -> Int + Threads.threadid([t::Task]) -> Int -Get the ID number of the current thread of execution. The master thread has -ID `1`. +Get the ID number of the current thread of execution, or the thread of task +`t`. The master thread has ID `1`. # Examples ```julia-repl @@ -21,12 +21,15 @@ julia> Threads.@threads for i in 1:4 2 5 4 + +julia> Threads.threadid(Threads.@spawn "foo") +2 ``` !!! note The thread that a task runs on may change if the task yields, which is known as [`Task Migration`](@ref man-task-migration). - For this reason in most cases it is not safe to use `threadid()` to index into, say, a vector of buffer or stateful objects. - + For this reason in most cases it is not safe to use `threadid([task])` to index into, say, a vector of buffers or stateful + objects. """ threadid() = Int(ccall(:jl_threadid, Int16, ())+1) diff --git a/base/timing.jl b/base/timing.jl index 5fefd75c15852..80ebb74abee26 100644 --- a/base/timing.jl +++ b/base/timing.jl @@ -1,6 +1,6 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -# This type must be kept in sync with the C struct in src/gc.h +# This type must be kept in sync with the C struct in src/gc-interface.h struct GC_Num allocd ::Int64 # GC internal deferred_alloc ::Int64 # GC internal @@ -47,7 +47,7 @@ gc_total_bytes(gc_num::GC_Num) = gc_num.allocd + gc_num.deferred_alloc + gc_num.total_allocd function GC_Diff(new::GC_Num, old::GC_Num) - # logic from `src/gc.c:jl_gc_total_bytes` + # logic from `jl_gc_total_bytes` old_allocd = gc_total_bytes(old) new_allocd = gc_total_bytes(new) return GC_Diff(new_allocd - old_allocd, diff --git a/contrib/bolt/Makefile b/contrib/bolt/Makefile index 2e911fcbcdc68..ea92ba9ff936a 100644 --- a/contrib/bolt/Makefile +++ b/contrib/bolt/Makefile @@ -52,7 +52,7 @@ FILES_TO_OPTIMIZE := $(shell for file in $(SYMLINKS_TO_OPTIMIZE); do readlink $( AFTER_INSTRUMENT_MESSAGE:='Run `make finish_stage1` to finish off the build. $\ You can now optionally collect more profiling data by running Julia with an appropriate workload, $\ if you wish, run `make clean_profiles` before doing so to remove any profiling data generated by `make finish_stage1`. $\ - You should end up with some data in $(PROFILE_DIR). Afterwards run `make merge_data && make bolt`. $\ + You should end up with some data in $(PROFILE_DIR). Afterwards run `make merge_data && make bolt`.' $(STAGE0_BUILD) $(STAGE1_BUILD): $(MAKE) -C $(JULIA_ROOT) O=$@ configure diff --git a/contrib/check-whitespace.jl b/contrib/check-whitespace.jl index e178ec8a02a38..fd3106587fb0d 100755 --- a/contrib/check-whitespace.jl +++ b/contrib/check-whitespace.jl @@ -18,6 +18,8 @@ const patterns = split(""" *Makefile """) +const is_gha = something(tryparse(Bool, get(ENV, "GITHUB_ACTIONS", "false")), false) + # Note: `git ls-files` gives `/` as a path separator on Windows, # so we just use `/` for all platforms. allow_tabs(path) = @@ -63,8 +65,14 @@ function check_whitespace() for (path, lineno, msg) in sort!(collect(errors)) if lineno == 0 println(stderr, "$path -- $msg") + if is_gha + println(stdout, "::warning title=Whitespace check,file=", path, "::", msg) + end else println(stderr, "$path:$lineno -- $msg") + if is_gha + println(stdout, "::warning title=Whitespace check,file=", path, ",line=", lineno, "::", msg) + end end end exit(1) diff --git a/contrib/download_cmake.sh b/contrib/download_cmake.sh index 1deeb08ddded2..5cf3c579ed052 100755 --- a/contrib/download_cmake.sh +++ b/contrib/download_cmake.sh @@ -8,17 +8,17 @@ mkdir -p "$(dirname "$0")"/../deps/scratch cd "$(dirname "$0")"/../deps/scratch CMAKE_VERSION_MAJOR=3 -CMAKE_VERSION_MINOR=19 -CMAKE_VERSION_PATCH=3 +CMAKE_VERSION_MINOR=30 +CMAKE_VERSION_PATCH=1 CMAKE_VERSION_MAJMIN=$CMAKE_VERSION_MAJOR.$CMAKE_VERSION_MINOR CMAKE_VERSION=$CMAKE_VERSION_MAJMIN.$CMAKE_VERSION_PATCH # listed at https://cmake.org/files/v$CMAKE_VERSION_MAJMIN/cmake-$CMAKE_VERSION-SHA-256.txt # for the files cmake-$CMAKE_VERSION-macos-universal.tar.gz # cmake-$CMAKE_VERSION-Linux-x86_64.tar.gz and cmake-$CMAKE_VERSION-Linux-aarch64.tar.gz -CMAKE_SHA256_DARWIN=a6b79ad05f89241a05797510e650354d74ff72cc988981cdd1eb2b3b2bda66ac -CMAKE_SHA256_LINUX_X86_64=c18b65697e9679e5c88dccede08c323cd3d3730648e59048047bba82097e0ffc -CMAKE_SHA256_LINUX_AARCH64=66e507c97ffb586d7ca6567890808b792c8eb004b645706df6fbf27826a395a2 +CMAKE_SHA256_DARWIN=51e12618829b811bba6f033ee8f39f6192da1b6abb20d82a7899d5134e879a4c +CMAKE_SHA256_LINUX_X86_64=ac31f077ef3378641fa25a3cb980d21b2f083982d3149a8f2eb9154f2b53696b +CMAKE_SHA256_LINUX_AARCH64=ad234996f8750f11d7bd0d17b03f55c434816adf1f1671aab9e8bab21a43286a PLATFORM="$(uname)-$(uname -m)" case $PLATFORM in @@ -28,12 +28,12 @@ case $PLATFORM in echo "$CMAKE_SHA256_DARWIN $FULLNAME.tar.gz" | shasum -a 256 -c - CMAKE_EXTRACTED_PATH=$FULLNAME/CMake.app/Contents/bin/cmake;; Linux-x86_64) - FULLNAME=cmake-$CMAKE_VERSION-$PLATFORM + FULLNAME=cmake-$CMAKE_VERSION-linux-x86_64 ../tools/jldownload https://cmake.org/files/v$CMAKE_VERSION_MAJMIN/$FULLNAME.tar.gz echo "$CMAKE_SHA256_LINUX_X86_64 $FULLNAME.tar.gz" | sha256sum -c - CMAKE_EXTRACTED_PATH=$FULLNAME/bin/cmake;; Linux-aarch64) - FULLNAME=cmake-$CMAKE_VERSION-$PLATFORM + FULLNAME=cmake-$CMAKE_VERSION-linux-aarch64 ../tools/jldownload https://cmake.org/files/v$CMAKE_VERSION_MAJMIN/$FULLNAME.tar.gz echo "$CMAKE_SHA256_LINUX_AARCH64 $FULLNAME.tar.gz" | sha256sum -c - CMAKE_EXTRACTED_PATH=$FULLNAME/bin/cmake;; diff --git a/contrib/pgo-lto-bolt/Makefile b/contrib/pgo-lto-bolt/Makefile index 6787b3bc4e919..fa88cdcd3d6a7 100644 --- a/contrib/pgo-lto-bolt/Makefile +++ b/contrib/pgo-lto-bolt/Makefile @@ -62,7 +62,7 @@ FILES_TO_OPTIMIZE := $(shell for file in $(SYMLINKS_TO_OPTIMIZE); do readlink $( AFTER_INSTRUMENT_MESSAGE:='Run `make finish_stage2` to finish off the build. $\ You can now optionally collect more profiling data by running Julia with an appropriate workload, $\ if you wish, run `make clean_profiles` before doing so to remove any profiling data generated by `make finish_stage2`. $\ - You should end up with some data in $(BOLT_PROFILE_DIR). Afterwards run `make merge_data && make bolt`. $\ + You should end up with some data in $(BOLT_PROFILE_DIR). Afterwards run `make merge_data && make bolt`.' # When building a single libLLVM.so we need to increase -vp-counters-per-site # significantly diff --git a/deps/BOLT.mk b/deps/BOLT.mk index 70c5d03c762ec..34391ab10f716 100644 --- a/deps/BOLT.mk +++ b/deps/BOLT.mk @@ -30,7 +30,7 @@ LLVM_LDFLAGS += $(LDFLAGS) LLVM_LDFLAGS += $(LLVM_LDFLAGS) LLVM_CMAKE += -DLLVM_TARGETS_TO_BUILD:STRING=host -DCMAKE_BUILD_TYPE=Release LLVM_CMAKE += -DLLVM_ENABLE_LIBXML2=OFF -DLLVM_HOST_TRIPLE="$(or $(XC_HOST),$(BUILD_MACHINE))" -LLVM_CMAKE += -DLLVM_ENABLE_ZLIB=ON -DZLIB_LIBRARY="$(build_prefix)/lib" +LLVM_CMAKE += -DLLVM_ENABLE_ZLIB=FORCE_ON -DZLIB_ROOT="$(build_prefix)" LLVM_CMAKE += -DLLVM_BINDINGS_LIST="" -DLLVM_ENABLE_BINDINGS=OFF -DLLVM_INCLUDE_DOCS=Off -DLLVM_ENABLE_TERMINFO=Off -DHAVE_LIBEDIT=Off diff --git a/deps/Makefile b/deps/Makefile index 2f9050f448d67..b87a3e1e58609 100644 --- a/deps/Makefile +++ b/deps/Makefile @@ -175,6 +175,10 @@ ifeq ($(WITH_NVTX),1) DEP_LIBS += nvtx endif +ifneq ($(WITH_TERMINFO),0) +DEP_LIBS += terminfo +endif + # Only compile standalone LAPACK if we are not using OpenBLAS. # OpenBLAS otherwise compiles LAPACK as part of its build. # This is useful where one wants to use the vendor BLAS, but @@ -197,7 +201,8 @@ DEP_LIBS_STAGED := $(DEP_LIBS) DEP_LIBS_STAGED_ALL := llvm llvm-tools clang llvmunwind unwind libuv pcre \ openlibm dsfmt blastrampoline openblas lapack gmp mpfr patchelf utf8proc \ objconv mbedtls libssh2 nghttp2 curl libgit2 libwhich zlib p7zip csl \ - sanitizers libsuitesparse lld libtracyclient ittapi nvtx JuliaSyntax + sanitizers libsuitesparse lld libtracyclient ittapi nvtx JuliaSyntax \ + terminfo DEP_LIBS_ALL := $(DEP_LIBS_STAGED_ALL) ifneq ($(USE_BINARYBUILDER_OPENBLAS),0) @@ -259,6 +264,7 @@ include $(SRCDIR)/libgit2.mk include $(SRCDIR)/libwhich.mk include $(SRCDIR)/p7zip.mk include $(SRCDIR)/libtracyclient.mk +include $(SRCDIR)/terminfo.mk # vendored Julia libs include $(SRCDIR)/JuliaSyntax.mk diff --git a/deps/blastrampoline.version b/deps/blastrampoline.version index 871053db3c9f2..fd055e1ae8120 100644 --- a/deps/blastrampoline.version +++ b/deps/blastrampoline.version @@ -2,6 +2,6 @@ BLASTRAMPOLINE_JLL_NAME := libblastrampoline ## source build -BLASTRAMPOLINE_VER := 5.10.1 -BLASTRAMPOLINE_BRANCH=v5.10.1 -BLASTRAMPOLINE_SHA1=ff05ebb4e450deda0aebe8dce4d4f054e23fecfc +BLASTRAMPOLINE_VER := 5.11.0 +BLASTRAMPOLINE_BRANCH=v5.11.0 +BLASTRAMPOLINE_SHA1=05083d50611b5538df69706f0a952d8e642b0b4b diff --git a/deps/checksums/JuliaSyntaxHighlighting-a463611e715c9ec546ac8463c38b6890d892e0c8.tar.gz/md5 b/deps/checksums/JuliaSyntaxHighlighting-a463611e715c9ec546ac8463c38b6890d892e0c8.tar.gz/md5 deleted file mode 100644 index 47635275f0364..0000000000000 --- a/deps/checksums/JuliaSyntaxHighlighting-a463611e715c9ec546ac8463c38b6890d892e0c8.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -5f8e876204d20c02b8139e61c78caf44 diff --git a/deps/checksums/JuliaSyntaxHighlighting-a463611e715c9ec546ac8463c38b6890d892e0c8.tar.gz/sha512 b/deps/checksums/JuliaSyntaxHighlighting-a463611e715c9ec546ac8463c38b6890d892e0c8.tar.gz/sha512 deleted file mode 100644 index d353acb42a5ce..0000000000000 --- a/deps/checksums/JuliaSyntaxHighlighting-a463611e715c9ec546ac8463c38b6890d892e0c8.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -e701477f0f7210854603e9d10758e2ecd47c1afb0f4ae6eca07cd64490cef74bbea5f3792f40b754dabbeea03bda2df07072c635b63e5f8a3f7ebb6f3f03fdf0 diff --git a/deps/checksums/JuliaSyntaxHighlighting-b89dd99db56700c47434df6106b6c6afd1c9ed01.tar.gz/md5 b/deps/checksums/JuliaSyntaxHighlighting-b89dd99db56700c47434df6106b6c6afd1c9ed01.tar.gz/md5 new file mode 100644 index 0000000000000..cbcb8097d1673 --- /dev/null +++ b/deps/checksums/JuliaSyntaxHighlighting-b89dd99db56700c47434df6106b6c6afd1c9ed01.tar.gz/md5 @@ -0,0 +1 @@ +3dc1387ed88ba3c0df04d05a86d804d0 diff --git a/deps/checksums/JuliaSyntaxHighlighting-b89dd99db56700c47434df6106b6c6afd1c9ed01.tar.gz/sha512 b/deps/checksums/JuliaSyntaxHighlighting-b89dd99db56700c47434df6106b6c6afd1c9ed01.tar.gz/sha512 new file mode 100644 index 0000000000000..2e58061d16058 --- /dev/null +++ b/deps/checksums/JuliaSyntaxHighlighting-b89dd99db56700c47434df6106b6c6afd1c9ed01.tar.gz/sha512 @@ -0,0 +1 @@ +fe30ed73b257e6928097cb7baca5b82a9a60b2f9b9f219fbcf570c5ed513447f0fda2a48da06b57e381516a69278f7f8519764d00e9e4fb5683a5411e245ef45 diff --git a/deps/checksums/Pkg-7aef1f044f3483e8b07d33fb4cfe918be554de69.tar.gz/md5 b/deps/checksums/Pkg-7aef1f044f3483e8b07d33fb4cfe918be554de69.tar.gz/md5 new file mode 100644 index 0000000000000..218260c77ea07 --- /dev/null +++ b/deps/checksums/Pkg-7aef1f044f3483e8b07d33fb4cfe918be554de69.tar.gz/md5 @@ -0,0 +1 @@ +832f88c404516179ece213581cd227f8 diff --git a/deps/checksums/Pkg-7aef1f044f3483e8b07d33fb4cfe918be554de69.tar.gz/sha512 b/deps/checksums/Pkg-7aef1f044f3483e8b07d33fb4cfe918be554de69.tar.gz/sha512 new file mode 100644 index 0000000000000..fc763c8d86f40 --- /dev/null +++ b/deps/checksums/Pkg-7aef1f044f3483e8b07d33fb4cfe918be554de69.tar.gz/sha512 @@ -0,0 +1 @@ +4355bb51a7f83bde489e587527e1e3a9c70799a5c0d27cd7f42b4227a5fbca2a1200a83db0317a75c582ee997bec72e9e8afafb059c395bd46e2aa015f481dca diff --git a/deps/checksums/Pkg-e4a6723bf3074764ff9266e5e13dfea501431b33.tar.gz/md5 b/deps/checksums/Pkg-e4a6723bf3074764ff9266e5e13dfea501431b33.tar.gz/md5 deleted file mode 100644 index 9151d83645ac6..0000000000000 --- a/deps/checksums/Pkg-e4a6723bf3074764ff9266e5e13dfea501431b33.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -e42b7400acc62aa5987dca1be49290ae diff --git a/deps/checksums/Pkg-e4a6723bf3074764ff9266e5e13dfea501431b33.tar.gz/sha512 b/deps/checksums/Pkg-e4a6723bf3074764ff9266e5e13dfea501431b33.tar.gz/sha512 deleted file mode 100644 index 5498d9f6a3069..0000000000000 --- a/deps/checksums/Pkg-e4a6723bf3074764ff9266e5e13dfea501431b33.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -71dd216051496210416db6a3489f9a934eb21ba59054fa921758e588450c6b1450f7771c8796d7b78ae3e481e0d730ad1bf48573dd2ec39975a840f9cc33114a diff --git a/deps/checksums/SparseArrays-0dd8d45d55b305458d0d3d3451057589b684f72f.tar.gz/md5 b/deps/checksums/SparseArrays-0dd8d45d55b305458d0d3d3451057589b684f72f.tar.gz/md5 new file mode 100644 index 0000000000000..7182cc71f7b35 --- /dev/null +++ b/deps/checksums/SparseArrays-0dd8d45d55b305458d0d3d3451057589b684f72f.tar.gz/md5 @@ -0,0 +1 @@ +2db86c7030acc973d5b46a87f32f7e99 diff --git a/deps/checksums/SparseArrays-0dd8d45d55b305458d0d3d3451057589b684f72f.tar.gz/sha512 b/deps/checksums/SparseArrays-0dd8d45d55b305458d0d3d3451057589b684f72f.tar.gz/sha512 new file mode 100644 index 0000000000000..a9e18eac9bfaa --- /dev/null +++ b/deps/checksums/SparseArrays-0dd8d45d55b305458d0d3d3451057589b684f72f.tar.gz/sha512 @@ -0,0 +1 @@ +0d3f54e7e75b48966e1816608d6ddf62175b92a0c778813a562df20750c6ecef9e4ccc24f9f3fffe4051d4b6765332add8c289fcdc598c320f400cec57a223a3 diff --git a/deps/checksums/SparseArrays-e61663ad0a79a48906b0b12d53506e731a614ab8.tar.gz/md5 b/deps/checksums/SparseArrays-e61663ad0a79a48906b0b12d53506e731a614ab8.tar.gz/md5 deleted file mode 100644 index d35cbc567faec..0000000000000 --- a/deps/checksums/SparseArrays-e61663ad0a79a48906b0b12d53506e731a614ab8.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -19f6d3bcbeec7a123e8dde983ef66a9a diff --git a/deps/checksums/SparseArrays-e61663ad0a79a48906b0b12d53506e731a614ab8.tar.gz/sha512 b/deps/checksums/SparseArrays-e61663ad0a79a48906b0b12d53506e731a614ab8.tar.gz/sha512 deleted file mode 100644 index f2c8db80327ce..0000000000000 --- a/deps/checksums/SparseArrays-e61663ad0a79a48906b0b12d53506e731a614ab8.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -8cef45d83047eba97edcaed04bb49f5aabdd96ec951baaa772c7da0402259e9578cfa383ab882440f685338ed14f797afe776a14e6aeea9df2428aa1592fcabf diff --git a/deps/checksums/StyledStrings-d7496d24d3f05536bce6a7eb4cd8ca05a75c02aa.tar.gz/md5 b/deps/checksums/StyledStrings-d7496d24d3f05536bce6a7eb4cd8ca05a75c02aa.tar.gz/md5 deleted file mode 100644 index 3a5fccdec0fba..0000000000000 --- a/deps/checksums/StyledStrings-d7496d24d3f05536bce6a7eb4cd8ca05a75c02aa.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -a02cd2c8bedd83b74917cf3821c89f46 diff --git a/deps/checksums/StyledStrings-d7496d24d3f05536bce6a7eb4cd8ca05a75c02aa.tar.gz/sha512 b/deps/checksums/StyledStrings-d7496d24d3f05536bce6a7eb4cd8ca05a75c02aa.tar.gz/sha512 deleted file mode 100644 index a042e4f306275..0000000000000 --- a/deps/checksums/StyledStrings-d7496d24d3f05536bce6a7eb4cd8ca05a75c02aa.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -2e86daa832533f0369e66e359d7d8f47002f93525f83233c809007a13dfd05a201bcd273b3cb4f3eba2586e98cc9afa43c242f67dc18b91fc898d98a0bd8fde9 diff --git a/deps/checksums/StyledStrings-f6035eb97b516862b16e36cab2ecc6ea8adc3d7c.tar.gz/md5 b/deps/checksums/StyledStrings-f6035eb97b516862b16e36cab2ecc6ea8adc3d7c.tar.gz/md5 new file mode 100644 index 0000000000000..0d39747d275ba --- /dev/null +++ b/deps/checksums/StyledStrings-f6035eb97b516862b16e36cab2ecc6ea8adc3d7c.tar.gz/md5 @@ -0,0 +1 @@ +bf7c157df6084942b794fbe5b768a643 diff --git a/deps/checksums/StyledStrings-f6035eb97b516862b16e36cab2ecc6ea8adc3d7c.tar.gz/sha512 b/deps/checksums/StyledStrings-f6035eb97b516862b16e36cab2ecc6ea8adc3d7c.tar.gz/sha512 new file mode 100644 index 0000000000000..d0a8d6cec08cf --- /dev/null +++ b/deps/checksums/StyledStrings-f6035eb97b516862b16e36cab2ecc6ea8adc3d7c.tar.gz/sha512 @@ -0,0 +1 @@ +ba2f6b91494662208842dec580ea9410d8d6ba4e57315c72e872227f5e2f68cc970fcf5dbd9c8a03920f93b6adabdeaab738fff04f9ca7b5da5cd6b89759e7f6 diff --git a/deps/checksums/SuiteSparse-e8285dd13a6d5b5cf52d8124793fc4d622d07554.tar.gz/md5 b/deps/checksums/SuiteSparse-e8285dd13a6d5b5cf52d8124793fc4d622d07554.tar.gz/md5 new file mode 100644 index 0000000000000..2f81a0d9191b5 --- /dev/null +++ b/deps/checksums/SuiteSparse-e8285dd13a6d5b5cf52d8124793fc4d622d07554.tar.gz/md5 @@ -0,0 +1 @@ +46541001073d1c3c85e18d910f8308f3 diff --git a/deps/checksums/SuiteSparse-e8285dd13a6d5b5cf52d8124793fc4d622d07554.tar.gz/sha512 b/deps/checksums/SuiteSparse-e8285dd13a6d5b5cf52d8124793fc4d622d07554.tar.gz/sha512 new file mode 100644 index 0000000000000..e2eb44845e276 --- /dev/null +++ b/deps/checksums/SuiteSparse-e8285dd13a6d5b5cf52d8124793fc4d622d07554.tar.gz/sha512 @@ -0,0 +1 @@ +f7470a447b934ca9315e216a07b97e363f11bc93186f9aa057b20b2d05092c58ae4f1b733de362de4a0730861c00be4ca5588d0b3ba65f018c1798b9122b9672 diff --git a/deps/checksums/blastrampoline b/deps/checksums/blastrampoline index b8c4c68c661ba..edb8cadc74846 100644 --- a/deps/checksums/blastrampoline +++ b/deps/checksums/blastrampoline @@ -1,34 +1,34 @@ -blastrampoline-ff05ebb4e450deda0aebe8dce4d4f054e23fecfc.tar.gz/md5/48ec847f7a687dd36789d6365d3c5645 -blastrampoline-ff05ebb4e450deda0aebe8dce4d4f054e23fecfc.tar.gz/sha512/85f6a46e7fe5f76ff8cef5776dad73b17eb97be3b16ca1af961cf2c2cbe125c629bd808b0243b793e4235dcb545a02cc082eaf14b3a438f3e0973d46921550a3 -libblastrampoline.v5.10.1+0.aarch64-apple-darwin.tar.gz/md5/cbbb4b5a6ebee04d686f072a69e855be -libblastrampoline.v5.10.1+0.aarch64-apple-darwin.tar.gz/sha512/32eaebb0fa3c0bc85a270b5c13fecaaa86ee10b4cea04405672badbaaa5ae3f22757dc758d9d971c811dc100a8ebd72fa00391238c0227de3690341f0434842a -libblastrampoline.v5.10.1+0.aarch64-linux-gnu.tar.gz/md5/da097a9459dcb8554f3d9511ea1a1c88 -libblastrampoline.v5.10.1+0.aarch64-linux-gnu.tar.gz/sha512/0159dbd4579d2a334f4341a64841bc1cef1354fc744709055339957b299b2b36b30162c2c90367abc04a2fb2f236aaa1fe6eb290393702f6fb97eaa79e4bb028 -libblastrampoline.v5.10.1+0.aarch64-linux-musl.tar.gz/md5/f32839481836dad6a1b159d9c33db752 -libblastrampoline.v5.10.1+0.aarch64-linux-musl.tar.gz/sha512/b973e739ab4af6ba93328943b03f16f02625553efc2375909b5e5bed4446287a21f99025817ce73267cac2d0b6b65f7dc2a5bd4b4c88d263b3c923b2ec3ad5c4 -libblastrampoline.v5.10.1+0.armv6l-linux-gnueabihf.tar.gz/md5/23eb2cbc1a547f94935fa4f9ffa2285b -libblastrampoline.v5.10.1+0.armv6l-linux-gnueabihf.tar.gz/sha512/0681497bac1d8f3ff1932adbb9fdd0b710b2a28ca7f2f4bb0093ba1123b14acd8bcb062e81e538c6e51ed8449ffea582cdb5b610e97d0c76a6feb58545938a6b -libblastrampoline.v5.10.1+0.armv6l-linux-musleabihf.tar.gz/md5/4e5168b1ada4e36861aeb3f4a6ace318 -libblastrampoline.v5.10.1+0.armv6l-linux-musleabihf.tar.gz/sha512/4ee663d2d3665e6ea356cfac60274c5f06ab08c1ee99b345ddda6872125663acb5559f704d0a918706e6cb075fc3071aaec4bcc3b9fee5fee72696e2f1454fb3 -libblastrampoline.v5.10.1+0.armv7l-linux-gnueabihf.tar.gz/md5/a28e3820fdf1435027f69204a553b5f9 -libblastrampoline.v5.10.1+0.armv7l-linux-gnueabihf.tar.gz/sha512/48edfc069aeaead468ffb6145986b11a040286990520b191e0f9cfa99f0b9458e6b17e523c8cc81889af7c9c2adce6372c65f2205a20c8e778614eaa06d288f9 -libblastrampoline.v5.10.1+0.armv7l-linux-musleabihf.tar.gz/md5/c5ea1756f3d58f8a74e76958f3a93658 -libblastrampoline.v5.10.1+0.armv7l-linux-musleabihf.tar.gz/sha512/f3eb003f954ffc346ae1037325b56fb2e4db9a6f88cc878862f921df79d8e0a5c8da9d229610dcd5d21c3d7af0a61ddcc0e70e32bf45fc9ea828d9ab2d1ddda8 -libblastrampoline.v5.10.1+0.i686-linux-gnu.tar.gz/md5/8bbdd602fed40577c4c9f020a8304c57 -libblastrampoline.v5.10.1+0.i686-linux-gnu.tar.gz/sha512/67947bd68c9f1131311d5d6a0fbcc92540f2fb2e1d2d0fa46951033fd75658661ba355c415b68de5dcd1bf0c440e27e3362ece70f5fd989fade796e9e723becd -libblastrampoline.v5.10.1+0.i686-linux-musl.tar.gz/md5/455bb539e7646e060fa24fb59c82f2f0 -libblastrampoline.v5.10.1+0.i686-linux-musl.tar.gz/sha512/e392334512ebce93ea4b34265ead802c543db5678c30083fb0dce08c071dd7140a9532d3162f215815807650138ffec5ad5d6d848025ee3913dfe353308d8e57 -libblastrampoline.v5.10.1+0.i686-w64-mingw32.tar.gz/md5/9a1c6845cb2e85b3497cd01d3a89b06b -libblastrampoline.v5.10.1+0.i686-w64-mingw32.tar.gz/sha512/66a9429a70575f4fd19d1cfb263c4c7801ac4a88408f98125f6e347b0ba35d2fdc4cbb82bf7407462beab1f7a7df2184163f76d5f2330f485bc1c7e5354716aa -libblastrampoline.v5.10.1+0.powerpc64le-linux-gnu.tar.gz/md5/b2b3eea1cfce87642a1f2afa125dcc5c -libblastrampoline.v5.10.1+0.powerpc64le-linux-gnu.tar.gz/sha512/43d5bf6535ad8f0910a523a3940787db956a3700681cc0dc1e2a1aabdaafa669e46e42854df29c0dcff06b3ade899159cb4845a48a6e618ba52af7276151fd0e -libblastrampoline.v5.10.1+0.x86_64-apple-darwin.tar.gz/md5/497a8f88c810a12b3faf12851427c784 -libblastrampoline.v5.10.1+0.x86_64-apple-darwin.tar.gz/sha512/7e3ed2117c6248761ba5bc3fd339f12ca98050d163d5c3668a62ee90aec10858d30fe9d78cea01796c9b2231cdd4f9ad0ae886bf8e984cb24d745e9f8c0fd62b -libblastrampoline.v5.10.1+0.x86_64-linux-gnu.tar.gz/md5/355612dc7c383dd860dc03498254814b -libblastrampoline.v5.10.1+0.x86_64-linux-gnu.tar.gz/sha512/12d803c53f705dacf2bf5f3884bd9b40f89a248ebda8bce1da6bba0cfe4331222bed5124dc45ea377e7c0fcc2d0dc624cc71b0eb454319fd12e2fd4c58d265f7 -libblastrampoline.v5.10.1+0.x86_64-linux-musl.tar.gz/md5/78a09fe918b1b0b3dc72c17c2e62799b -libblastrampoline.v5.10.1+0.x86_64-linux-musl.tar.gz/sha512/1ff3d7e8d36d450f430119b30e03a64f2d78d6d13a04e4a4b97c64966e341f486080c733dbd73ee3ed7c1557ad737f37c013335578e1555d162f0591929de747 -libblastrampoline.v5.10.1+0.x86_64-unknown-freebsd.tar.gz/md5/ad9f213bc4a7882784ad09017fc82234 -libblastrampoline.v5.10.1+0.x86_64-unknown-freebsd.tar.gz/sha512/4de6f08a45cb3c3819f71ccd44688b847c2e9b36e0d4bce94191558fe2d775c2790f4c68eea1a366d0a869f0c986aa33626d427946403cf4e128f45b5881f70e -libblastrampoline.v5.10.1+0.x86_64-w64-mingw32.tar.gz/md5/2d0cf117d8d797e7716f8d836dfdd9f5 -libblastrampoline.v5.10.1+0.x86_64-w64-mingw32.tar.gz/sha512/d7a94f3a71400b22b6c14648455e38dff750eb88661928b66b307f721d53769dea3aec43bb86e2200145ed072475c32e1bfc38e0fc35445c4c42e5752754b0e5 +blastrampoline-05083d50611b5538df69706f0a952d8e642b0b4b.tar.gz/md5/700b22cb26291736bd1263cd2a7f2d75 +blastrampoline-05083d50611b5538df69706f0a952d8e642b0b4b.tar.gz/sha512/967c16d28834df112916c0904dd4c7231a1c5e4edf279adb26411faa17da28eee4680ce2347b3941520dccbc768944277a8f724b21976960d00f840349b90e36 +libblastrampoline.v5.11.0+0.aarch64-apple-darwin.tar.gz/md5/769458d40e004d6126cae6b34351068f +libblastrampoline.v5.11.0+0.aarch64-apple-darwin.tar.gz/sha512/75a726b9a4f41b70344ceb9e1f1a7ad370bfa84ce44c70b8a965061d777871e3bf2237ae055da7e6202ddef78932ba8baf2a01a675b1b0cec5338ef16ea2081b +libblastrampoline.v5.11.0+0.aarch64-linux-gnu.tar.gz/md5/d92cf3f3fa1e977ea3a1a74acc8442d1 +libblastrampoline.v5.11.0+0.aarch64-linux-gnu.tar.gz/sha512/3354f4eec2a410f81cc0546a04ce98ddd416d441c1701a59ec5bebea99af8823b5af10a85cb4e3377548422c6d6a0a870f2e7a05ad0cda52c6143361d59ba4fb +libblastrampoline.v5.11.0+0.aarch64-linux-musl.tar.gz/md5/41d060c03202b662e47bda5fbf7b1e84 +libblastrampoline.v5.11.0+0.aarch64-linux-musl.tar.gz/sha512/54a05516e12350441c33341fde53bc912aa52dc4b746089c2d21cb75f24f0fb140849a520327db6f52895743eab090b59fa974a2a426a49f8b4e38693340a306 +libblastrampoline.v5.11.0+0.armv6l-linux-gnueabihf.tar.gz/md5/4930dceefac63e7aa5a93e1ba0e00e59 +libblastrampoline.v5.11.0+0.armv6l-linux-gnueabihf.tar.gz/sha512/dafce083c2b409ead61fdbdf4f46b7c93cab00c82a74a181d381c4a93f1e7af035cd6caf407b0199c1f8c2f2f68f93d67938ef092fa4a8d1133f0ea73fb51a9c +libblastrampoline.v5.11.0+0.armv6l-linux-musleabihf.tar.gz/md5/82346cc4ddeaa29ea7a081edfdfcb08b +libblastrampoline.v5.11.0+0.armv6l-linux-musleabihf.tar.gz/sha512/72e387bd661096a46077e8c15e12f8a6f18fd6aaf30af0678d00eca0d83af10758874643f5716539dd38269e831e4649d45db739aeb60996bf1b96277cea1d17 +libblastrampoline.v5.11.0+0.armv7l-linux-gnueabihf.tar.gz/md5/7e8f115268e8c62acaa2a53ecd32e2fe +libblastrampoline.v5.11.0+0.armv7l-linux-gnueabihf.tar.gz/sha512/4210c306ff7ccb53aa6c9f45e134c63b238c563ed753f7536dfc21f6962dfea35d9de62e429e2685b70d0db780ac766b72fd5e76e2d62df74000e3e5d553c30f +libblastrampoline.v5.11.0+0.armv7l-linux-musleabihf.tar.gz/md5/7f388611c477b528a091f697b0d334d9 +libblastrampoline.v5.11.0+0.armv7l-linux-musleabihf.tar.gz/sha512/e9b017dfa8c19cb940395b253f3b28511a6619469fabff7ab1671ed0936e9e0681d1385c3d1f5d6417ccb65ffbdcf53a0c8519d4ef8e89f9500a05ca00296144 +libblastrampoline.v5.11.0+0.i686-linux-gnu.tar.gz/md5/254948ea87a435251b1e064a77b3d635 +libblastrampoline.v5.11.0+0.i686-linux-gnu.tar.gz/sha512/5a51d3c20c49c497a8f0c2d2e7b38b49ec5e367c7013a7f0efa4fc099639da20ef9c0bfdbdfbdc40b27ce61f189b18f5cf617d7a0ed4bc5300da692f7d6b77a4 +libblastrampoline.v5.11.0+0.i686-linux-musl.tar.gz/md5/a9504870af8db1e247be02c5e188f7a5 +libblastrampoline.v5.11.0+0.i686-linux-musl.tar.gz/sha512/5f0109168a16edb8ca66fcf10c2c10b57fe9c3061c0b08dac4dea936538fa5854aa1b66079f127b5d9902288b61772054013256aa307b682de38e350b1bbb367 +libblastrampoline.v5.11.0+0.i686-w64-mingw32.tar.gz/md5/815822f6bacb42c35b80bc77458c5c49 +libblastrampoline.v5.11.0+0.i686-w64-mingw32.tar.gz/sha512/c82f8c6fe0b7917860e5601c79e35d56297c53b6f7f992841d4f048e7981533e459f9db0805a16d82a9e03d452489760def0d9c57181dcfa5dc363102180eecd +libblastrampoline.v5.11.0+0.powerpc64le-linux-gnu.tar.gz/md5/ee30c9cb4c51df03026f9e471040e9cc +libblastrampoline.v5.11.0+0.powerpc64le-linux-gnu.tar.gz/sha512/5055d83a1b0625364ddd97652a4c6fa39c795078123cad33a085283889274f66c9dc053be0591c14be262dc7eef666726afa922c66ae8d05c2791c3d6bd7009e +libblastrampoline.v5.11.0+0.x86_64-apple-darwin.tar.gz/md5/210cd354c9b4a8aa2a2b55723597e58b +libblastrampoline.v5.11.0+0.x86_64-apple-darwin.tar.gz/sha512/1ee65d598f9f8a2cf7137135c8c2c431520b1cde319fc33dddfbdae9fe01d986e979a97c24cf85c090cc40064cfe47c376dfeb088ff417d17868c4df84fb2fd4 +libblastrampoline.v5.11.0+0.x86_64-linux-gnu.tar.gz/md5/e2213c42eebee6e45079ef6831077b3f +libblastrampoline.v5.11.0+0.x86_64-linux-gnu.tar.gz/sha512/ab2c3026d34962a2ca5116d71a4e8eaaca5182d53f21edd3e4be81ce26e74e427c88797308af7fbbf1b9ee615e0383acf0dae1d0eb207ebc64dddaf927f00b48 +libblastrampoline.v5.11.0+0.x86_64-linux-musl.tar.gz/md5/8cde3c618e882ea2b7c8a017a69175c7 +libblastrampoline.v5.11.0+0.x86_64-linux-musl.tar.gz/sha512/8a3aca5691c3936d114c804471b2429b9ae81308f020247765614d2f792f93a012263ce4baa31cf42f4dacc23a7161a4c7f9debfba8d9028879f1ed3fc4e2433 +libblastrampoline.v5.11.0+0.x86_64-unknown-freebsd.tar.gz/md5/b02eb694e1486ef8ffe9534ac2bd5ec6 +libblastrampoline.v5.11.0+0.x86_64-unknown-freebsd.tar.gz/sha512/989273809ae567d7e7193529740423ac1870eae3a0effeecc67f84da914d81649786f393e101f013b7232ef5fe35066d89b3cb776ad0e87394799491ef28a467 +libblastrampoline.v5.11.0+0.x86_64-w64-mingw32.tar.gz/md5/6e7f602ab0bf5a5c28bf4e959a1bbf77 +libblastrampoline.v5.11.0+0.x86_64-w64-mingw32.tar.gz/sha512/556e7ca1a2576c1d7825ac1bc2449ffe2cd40391cf316b10f60681a5c736939c97eb5221c2837640928b5544f89f44cb14ca44ccf54092376390ea1a6012c9e5 diff --git a/deps/checksums/clang b/deps/checksums/clang index ee3dc2125ea30..7dc297db9c05b 100644 --- a/deps/checksums/clang +++ b/deps/checksums/clang @@ -1,108 +1,108 @@ -Clang.v17.0.6+4.aarch64-apple-darwin-llvm_version+17.asserts.tar.gz/md5/5a9351db0940c66e9646e0f3d6f37e1a -Clang.v17.0.6+4.aarch64-apple-darwin-llvm_version+17.asserts.tar.gz/sha512/bf344cfe91795cfc4419ea9ec50df99237b64c57e0b81655a957b15ecc5b16f0134daf189f18fe34274df8de679d407b36f82e3723e80428afb456215a5b9a20 -Clang.v17.0.6+4.aarch64-apple-darwin-llvm_version+17.tar.gz/md5/6c7461a52e07a1e3ecf9911784bb26cb -Clang.v17.0.6+4.aarch64-apple-darwin-llvm_version+17.tar.gz/sha512/ce63de6405cd7c34d640afb259de8056db175e55bece923ce53c39b88dccc2885de70f4c598b3282102754b0c7cf6ac602e827968b6509fd7affa20ecf07d1a5 -Clang.v17.0.6+4.aarch64-linux-gnu-cxx03-llvm_version+17.asserts.tar.gz/md5/5446f22e4aba17482c057ee79beb2086 -Clang.v17.0.6+4.aarch64-linux-gnu-cxx03-llvm_version+17.asserts.tar.gz/sha512/372be10dd8752821c751e571a5a9fc4af328285dcad6f2213f6e3d54f819405c26f1a1cb1e712d4bffebe3a42ca0736903d59ba70602a8ddd96b9e6fdfb9bacf -Clang.v17.0.6+4.aarch64-linux-gnu-cxx03-llvm_version+17.tar.gz/md5/ca146aa3731ef24300c8398ddfb7ffd4 -Clang.v17.0.6+4.aarch64-linux-gnu-cxx03-llvm_version+17.tar.gz/sha512/2459729a3af81fb962c7491ff16209fe6b65f4ef2f8323857b7c548da506d227a42a9b3301b8c8465cff66bbc9acbff2ac3e86d1a8560b9cb701b133317cd730 -Clang.v17.0.6+4.aarch64-linux-gnu-cxx11-llvm_version+17.asserts.tar.gz/md5/68c478b00a6cb1ecf700b54c86acc584 -Clang.v17.0.6+4.aarch64-linux-gnu-cxx11-llvm_version+17.asserts.tar.gz/sha512/669af6e27ee67ea1be7f70cc328193d6139161264e1f6ef85c31c62523997246050d8b8aa241b257a191a9566df1f3ea620641c676908b817d5dfe7519ba0c8e -Clang.v17.0.6+4.aarch64-linux-gnu-cxx11-llvm_version+17.tar.gz/md5/a299ea50c4862dcd0832cc483aa9c172 -Clang.v17.0.6+4.aarch64-linux-gnu-cxx11-llvm_version+17.tar.gz/sha512/e42e2e09be2872d2e1c57a46099b92847873dd4ebc87801cbd5fc171bbb236ef8bb815c4fd481d4a804fd6604fcb3cee7ee6fa66e712cc7a2fc2434d0649932a -Clang.v17.0.6+4.aarch64-linux-musl-cxx03-llvm_version+17.asserts.tar.gz/md5/804ec7eeb6b2fd8fb6ad9537bebc0f3e -Clang.v17.0.6+4.aarch64-linux-musl-cxx03-llvm_version+17.asserts.tar.gz/sha512/36cda1267528e54658b28d31ed4218ecb11c2a05e161faf80030a899d2cb1d1ed145bdf19f7565853277230428d521a2b33759df09e0e799226b44d477c2de46 -Clang.v17.0.6+4.aarch64-linux-musl-cxx03-llvm_version+17.tar.gz/md5/4fd80844867e14a1a245c2ed911942bc -Clang.v17.0.6+4.aarch64-linux-musl-cxx03-llvm_version+17.tar.gz/sha512/acc6a4d240b54682425f40d8c5b6e3578d818b03430696c3c90cde8ad8474de5692468379cfc7f4d826bd44a6fb38cdc036df9d31833d09477fb69ae569e160c -Clang.v17.0.6+4.aarch64-linux-musl-cxx11-llvm_version+17.asserts.tar.gz/md5/1774c2ed22a44aab72d7cf58c8a85ab0 -Clang.v17.0.6+4.aarch64-linux-musl-cxx11-llvm_version+17.asserts.tar.gz/sha512/686b2bd8af2f47b03b25e23ac2d2954e5b9ccdcd942fcc6ccb9b96240a1fe414ac73d88f173dfdf93f45eb609e99299041a6a976a90b7afc6e49b698b6403a94 -Clang.v17.0.6+4.aarch64-linux-musl-cxx11-llvm_version+17.tar.gz/md5/e5e0d42647b5b50102f68e76823be11f -Clang.v17.0.6+4.aarch64-linux-musl-cxx11-llvm_version+17.tar.gz/sha512/72b112ab6714d67c33088c978420f996a45c6fd1900ab1725908792a5b8a0f0407ecf53817761059fa4bebd81a443680c8cd1c25633a2eb702986a23072d7b70 -Clang.v17.0.6+4.armv6l-linux-gnueabihf-cxx03-llvm_version+17.asserts.tar.gz/md5/9601966aed6cdf5af9b6da24bf088ef8 -Clang.v17.0.6+4.armv6l-linux-gnueabihf-cxx03-llvm_version+17.asserts.tar.gz/sha512/c70448ed703f74c0f82c43ba35bf3a1f4f02832e42bea795b5ae0caae1e3b8aa0fdd914b3a6753a68b9f0a7d3a5156e56fad35bd6fff15bc5566f74db26ce3ca -Clang.v17.0.6+4.armv6l-linux-gnueabihf-cxx03-llvm_version+17.tar.gz/md5/3aa7b1d67c252aab4cfb85a665ecf194 -Clang.v17.0.6+4.armv6l-linux-gnueabihf-cxx03-llvm_version+17.tar.gz/sha512/7575858507e07b94001200c4d4e9875a2a4c8b97074655a1c1c03edd8cd2bbe853cca3a518d36d6f3243649839aa53d4dbe2e637eaf9b93873b2dd82266d4e17 -Clang.v17.0.6+4.armv6l-linux-gnueabihf-cxx11-llvm_version+17.asserts.tar.gz/md5/7729c1ebdde07122fd0f9ae63a14c34f -Clang.v17.0.6+4.armv6l-linux-gnueabihf-cxx11-llvm_version+17.asserts.tar.gz/sha512/04fe96e57a5351c3265441b73919900f1d19220747aa8ac061ef15531ee3f6bd62a70a4405c615c3b14975250b039d81fabde3b351c6e2118e684ca479eacbaa -Clang.v17.0.6+4.armv6l-linux-gnueabihf-cxx11-llvm_version+17.tar.gz/md5/37536e1d18b6b0a948b83ebcee530af0 -Clang.v17.0.6+4.armv6l-linux-gnueabihf-cxx11-llvm_version+17.tar.gz/sha512/d94c3bd7afbca9dc81bb10a4d0e041165e63a2ac9dfcc1483bd55da1091c664074e9a26c9972da23adca3f711ffd22ba517546f0f0e58b717f3043973def0e97 -Clang.v17.0.6+4.armv6l-linux-musleabihf-cxx03-llvm_version+17.asserts.tar.gz/md5/ded5fe5d4de1c3bfd0fc75494c44cb11 -Clang.v17.0.6+4.armv6l-linux-musleabihf-cxx03-llvm_version+17.asserts.tar.gz/sha512/85f6df75ed2b67fe9dcdea745ac1e659c0335c17c54b03c964d6996e926303fbf14c1c2ed6b369ffa38bde827c9894c32de82afa562673dad3268c43985dc7ce -Clang.v17.0.6+4.armv6l-linux-musleabihf-cxx03-llvm_version+17.tar.gz/md5/e4eac3b4bfa0e3b825cd23f88738bd3a -Clang.v17.0.6+4.armv6l-linux-musleabihf-cxx03-llvm_version+17.tar.gz/sha512/c0552d1c9dbfe73b07f3ea2907d879c1142e8f6db6530297ee977c2b23858a9f55674f635a4746262e7595af2ca41a752a6abb4944e6707f4daa3a8c0715df83 -Clang.v17.0.6+4.armv6l-linux-musleabihf-cxx11-llvm_version+17.asserts.tar.gz/md5/4b5f66f39069204ba7281740115b7ef7 -Clang.v17.0.6+4.armv6l-linux-musleabihf-cxx11-llvm_version+17.asserts.tar.gz/sha512/4c789017ec2bd98e808d198a8baefb2405222efb6e93eb5d1b8944dbd1e587afc41ebaf506b0aed5def5eb4c815ef4c822e0e0477b4aaac35fc03f9850853be3 -Clang.v17.0.6+4.armv6l-linux-musleabihf-cxx11-llvm_version+17.tar.gz/md5/95310b525b635b8c6550226e2b9fe02b -Clang.v17.0.6+4.armv6l-linux-musleabihf-cxx11-llvm_version+17.tar.gz/sha512/faa62d41124b92d829658397eaada3ee8ce41f2e36e7f9954bd3fdd882a1232bf3431f36c9b7e65c17ae4f228da9ac37e1db0b1ae43a8540765186a230c65bab -Clang.v17.0.6+4.armv7l-linux-gnueabihf-cxx03-llvm_version+17.asserts.tar.gz/md5/5886d8e09d76ed74c2293c0af8be413f -Clang.v17.0.6+4.armv7l-linux-gnueabihf-cxx03-llvm_version+17.asserts.tar.gz/sha512/ca66bb3bd39b7643cf0dcb551a6bb7a3293f4c99f8d4ae1fc16eb66a0f0da0ef10acae52169b2522dc2fdebc1f550d2d36b87bb25d9b1c9df0a8f0d5089c7642 -Clang.v17.0.6+4.armv7l-linux-gnueabihf-cxx03-llvm_version+17.tar.gz/md5/7b08c562565e408d716898bf37e44eda -Clang.v17.0.6+4.armv7l-linux-gnueabihf-cxx03-llvm_version+17.tar.gz/sha512/e9051454cc15a7879d90e6b36eeaf4c956e328be7823a1fa37cb98197c0fb4dddb9aaa8cf7aedd35e0affa9e6876b79f9a1160da1ec4d26ea7c775db58293dd2 -Clang.v17.0.6+4.armv7l-linux-gnueabihf-cxx11-llvm_version+17.asserts.tar.gz/md5/dc816bd807c9d131e088c30caad9d326 -Clang.v17.0.6+4.armv7l-linux-gnueabihf-cxx11-llvm_version+17.asserts.tar.gz/sha512/5700dcef831b52abf64cc9120352918c302301e19ecf6ac64aa2cfb6270f7b2c82fe3f0f1d3281539081db7d520e2301995d992b9e8234cf64d7ec88126f4bc8 -Clang.v17.0.6+4.armv7l-linux-gnueabihf-cxx11-llvm_version+17.tar.gz/md5/971caa23440c190b085300f4cd67b080 -Clang.v17.0.6+4.armv7l-linux-gnueabihf-cxx11-llvm_version+17.tar.gz/sha512/5ce854fee306c14ef7964e3ab9831e816c6eefab637221b71be2187f42e7b089c1dd9e92754ab5ee3198bb3c0e84da9a2cc15c2d6afcb086f61b897cfc320ab3 -Clang.v17.0.6+4.armv7l-linux-musleabihf-cxx03-llvm_version+17.asserts.tar.gz/md5/5ad3e0a391db624713263226259b55f0 -Clang.v17.0.6+4.armv7l-linux-musleabihf-cxx03-llvm_version+17.asserts.tar.gz/sha512/ed4cf7c241bbaca9f887cfb81caca687e3f30d01922e05c72b435c6333b334fa4f708193b8c85de9777f9912fcd8a55b1d7a6cd1aef00b913f0d0f1439e9ed6f -Clang.v17.0.6+4.armv7l-linux-musleabihf-cxx03-llvm_version+17.tar.gz/md5/5d487035d147bc48655e5538f08afbdf -Clang.v17.0.6+4.armv7l-linux-musleabihf-cxx03-llvm_version+17.tar.gz/sha512/f26d96241b9b18609c1d4148e30048d73faed24fe3f623a5d2bc6aaa59a644cc97201acfbde2eed4daecc79602e6d13256e112c8b821b6d865d071db957268a2 -Clang.v17.0.6+4.armv7l-linux-musleabihf-cxx11-llvm_version+17.asserts.tar.gz/md5/fdcf70b4514c3d63498a3fa46a2525c2 -Clang.v17.0.6+4.armv7l-linux-musleabihf-cxx11-llvm_version+17.asserts.tar.gz/sha512/d481c807405302eabc612075e22acc9f7d1cbdbb17de23b6a129dfba60c265eacf20cc2d48d5b4087979b1184a783bcd0bf6ed326060e5ef05119556f21a5a95 -Clang.v17.0.6+4.armv7l-linux-musleabihf-cxx11-llvm_version+17.tar.gz/md5/a8a04c92d74dcd22f980956d2b7ccb71 -Clang.v17.0.6+4.armv7l-linux-musleabihf-cxx11-llvm_version+17.tar.gz/sha512/af3ad3efc2941b98ca4ec1340e24beb1c1f1c5d2248da3000af3f2e7184df013b55127040cfd03a63acd461acdb4f1afcc6b11f1ad11502aa86f737629c185a2 -Clang.v17.0.6+4.i686-linux-gnu-cxx03-llvm_version+17.asserts.tar.gz/md5/15d02f2f91fcdd52d641991d58b15c9b -Clang.v17.0.6+4.i686-linux-gnu-cxx03-llvm_version+17.asserts.tar.gz/sha512/e1903be2164fb3002a93829a295d2a413c14faa2a0fad2297763a6cbd63ec0bcc37689cbec4c0f0bd0f4eb4cddc716f78d57c95f7ed29145ffed3b7c50a98d04 -Clang.v17.0.6+4.i686-linux-gnu-cxx03-llvm_version+17.tar.gz/md5/cfaab26c1c8409362a267484c2ccfbc1 -Clang.v17.0.6+4.i686-linux-gnu-cxx03-llvm_version+17.tar.gz/sha512/2f9bb137df4666f9c2947a74a4a06489d477b5093c3b0acae11d6c1213c467e258aaa360183f8b18ca28778773a5170f5dd19ea3622294f0d715a5909c6d06ed -Clang.v17.0.6+4.i686-linux-gnu-cxx11-llvm_version+17.asserts.tar.gz/md5/6bb27685277eae5289f782657925c33a -Clang.v17.0.6+4.i686-linux-gnu-cxx11-llvm_version+17.asserts.tar.gz/sha512/35bd7b862b2a2aa372be7f0bb01aa65dc58f71d2218833ca39f832a25c3162b3282c9806f3cdc4a9a2a7bc11167a6daec30b688b979f1a38f49fa412e4628648 -Clang.v17.0.6+4.i686-linux-gnu-cxx11-llvm_version+17.tar.gz/md5/f44f9fdebc843c5947d1777e53c4189f -Clang.v17.0.6+4.i686-linux-gnu-cxx11-llvm_version+17.tar.gz/sha512/09d1f9a29bdd04e598622cca11e0a82ef6a68f0ac9d4e6fada548482fff6219cef5714bdd3d02d1c0944de14ef14991ee0eab9b4f54c4efacae330a9e4ac47dc -Clang.v17.0.6+4.i686-w64-mingw32-cxx03-llvm_version+17.asserts.tar.gz/md5/0d7c790218fe40d1f87850197a5d08df -Clang.v17.0.6+4.i686-w64-mingw32-cxx03-llvm_version+17.asserts.tar.gz/sha512/fac636c5ede5baf7d5c706f348b8992d4bf0042cb34decb83964385d9877b7555db998fc79cd7f032d80b3572275f13fbc36ccf5a76e573221266e1ee339ec76 -Clang.v17.0.6+4.i686-w64-mingw32-cxx03-llvm_version+17.tar.gz/md5/5d4f5b78645f75b93e76a75efdad721f -Clang.v17.0.6+4.i686-w64-mingw32-cxx03-llvm_version+17.tar.gz/sha512/a013697f1da103a1202a1728ebfc61ec0d08e705e0caa253cd14430abfa3d47a7b43930d3d9d70d995dbb1e5f78eebd02ef8cbfd9b028b447a3b7953d437a60d -Clang.v17.0.6+4.i686-w64-mingw32-cxx11-llvm_version+17.asserts.tar.gz/md5/8d9b46562cefc0ce9b7dfd6022cb914c -Clang.v17.0.6+4.i686-w64-mingw32-cxx11-llvm_version+17.asserts.tar.gz/sha512/95d8cd716bfbff69d336987a3ff0f65e28f48544679cf6bd165319cd5382f0eb9d5be119917a5b309e7544e43ac7c52f1370d159e67f18ff2eda06cf7bad31f5 -Clang.v17.0.6+4.i686-w64-mingw32-cxx11-llvm_version+17.tar.gz/md5/86bf7e43fa750d620495eb73c938273c -Clang.v17.0.6+4.i686-w64-mingw32-cxx11-llvm_version+17.tar.gz/sha512/1a014fa2ec455fee7be9413fa1db901360e5728bcfffb7bb76fd3b30b00120883c91f4ebfcfe048e5f372bdcc18a2a45744ddb1e8c7e303d5952af49e386caff -Clang.v17.0.6+4.powerpc64le-linux-gnu-cxx03-llvm_version+17.asserts.tar.gz/md5/c125dafc105894bb0bb821bb7b28ce3a -Clang.v17.0.6+4.powerpc64le-linux-gnu-cxx03-llvm_version+17.asserts.tar.gz/sha512/6da75d2fdc18ba95dd3db9181401a4ac0b7f8e465ad872f95f2e9db49701cc56da7c13f6ca69b01e15832f9bf23cd698ca5dcb28dcf775edef6bd5728ca669ca -Clang.v17.0.6+4.powerpc64le-linux-gnu-cxx03-llvm_version+17.tar.gz/md5/4b9d2090af04573a35c0d80833f9212d -Clang.v17.0.6+4.powerpc64le-linux-gnu-cxx03-llvm_version+17.tar.gz/sha512/7e9231e286f15b4d90318a732d1fae3130a1d6714f6cf868f5d3472068b719818e4d2a63dfbb2056e1f3e7f2a25250c4de1f0629e459b36f7d8e1e42286470c0 -Clang.v17.0.6+4.powerpc64le-linux-gnu-cxx11-llvm_version+17.asserts.tar.gz/md5/7762d01fc07748336997bee900003653 -Clang.v17.0.6+4.powerpc64le-linux-gnu-cxx11-llvm_version+17.asserts.tar.gz/sha512/c7334dfaa5317b89a58beb0b397a2784036c98fa3434f67efcbfd1ee9375a195ebfedbfcc2f7ddde00a518e2a175cd821e11b887a913499c10d60940c7cdbe43 -Clang.v17.0.6+4.powerpc64le-linux-gnu-cxx11-llvm_version+17.tar.gz/md5/4d4388d2e621d71e390579d0684776d6 -Clang.v17.0.6+4.powerpc64le-linux-gnu-cxx11-llvm_version+17.tar.gz/sha512/b5dee74f399ed7422fc1dbb3321b8c216fe434ca57440c4ee51293b2478ef007df9f8d1031e714496014309ac8eabee4c7c884272181c0713253f43e1bcab3e6 -Clang.v17.0.6+4.x86_64-apple-darwin-llvm_version+17.asserts.tar.gz/md5/927779c5fe29a5beb2d4bf0668a0fae2 -Clang.v17.0.6+4.x86_64-apple-darwin-llvm_version+17.asserts.tar.gz/sha512/3c16687184eaf180b5a6861a4b96ddf0d099769bbfb21265ed434575c537b10a30803924f05aa53ec0684cce8b8ae31f3082124130d4a4ae31b717bfc01e7442 -Clang.v17.0.6+4.x86_64-apple-darwin-llvm_version+17.tar.gz/md5/5c08fb48aa15c5ee9667a3e177f19851 -Clang.v17.0.6+4.x86_64-apple-darwin-llvm_version+17.tar.gz/sha512/aa773bb698145fb4040c34d787d959c0db71c90da5a5e5bf6799d287fd7925049169fa1a681742e12f81a32156b1d958c2f1d92295888cf50ccd4b84fd798625 -Clang.v17.0.6+4.x86_64-linux-gnu-cxx03-llvm_version+17.asserts.tar.gz/md5/302b59a86820fa43b0f62c8788f4129f -Clang.v17.0.6+4.x86_64-linux-gnu-cxx03-llvm_version+17.asserts.tar.gz/sha512/543fad08f4d22a8ee5a25c29b81f8e6df729e19bd31d94cbb48d5cd9bf451fffdad692209d9a0a98583bd1cb22d3a783ecc140c10c65da58ebb1b727311aeea1 -Clang.v17.0.6+4.x86_64-linux-gnu-cxx03-llvm_version+17.tar.gz/md5/5e904bd57f12999826ef39bc37382c76 -Clang.v17.0.6+4.x86_64-linux-gnu-cxx03-llvm_version+17.tar.gz/sha512/adb8061bc2debde834722b7965d4dc8ee5ea5a5fd5459eb84f872e13cb40a38d2e923f5dbe06cff5138e6cf065d9ce91e52ac395a586f0ac9c6f4f2fe1e4f0d1 -Clang.v17.0.6+4.x86_64-linux-gnu-cxx11-llvm_version+17.asserts.tar.gz/md5/806b042515bb8294bacf37dd804dd303 -Clang.v17.0.6+4.x86_64-linux-gnu-cxx11-llvm_version+17.asserts.tar.gz/sha512/dabb1c73f477ca97ae2d84846ed937f084ceb9abcdd614a0fdbcab7b9d863ed8544ba25fc25f99df40254c964eb4abf89ed61bf4a61f680607e8d096f71a837f -Clang.v17.0.6+4.x86_64-linux-gnu-cxx11-llvm_version+17.tar.gz/md5/1e92606453daf98bbb5879aef9a0b97f -Clang.v17.0.6+4.x86_64-linux-gnu-cxx11-llvm_version+17.tar.gz/sha512/f262e08e2b36dace3f7cae645709627368a221bc7d3a081e501f5a95797ef36e9c63071f17d722ee546e0993502c171049f285e22f665e3998e1a408e3adcdf0 -Clang.v17.0.6+4.x86_64-linux-musl-cxx03-llvm_version+17.asserts.tar.gz/md5/d5519cf744be4d311c5a6ce97cd26d6e -Clang.v17.0.6+4.x86_64-linux-musl-cxx03-llvm_version+17.asserts.tar.gz/sha512/5ef23e8b5c0a828974dfa578eae68255e01c461f7d4bf10ec43f0bb4d2fe3b88c649dde8fe534550c602ceb835f7e736aa7d0b642c7ed21aa725c06c3bd4890f -Clang.v17.0.6+4.x86_64-linux-musl-cxx03-llvm_version+17.tar.gz/md5/22831802bfc779bac31c3b5fd5b613e5 -Clang.v17.0.6+4.x86_64-linux-musl-cxx03-llvm_version+17.tar.gz/sha512/94be9e0c6c077409f8eadbdfd8ddc83901bf36f095563e630ba02a86234f30d67d4bff6df2cc33e1c52e494f231f33538ce1f8a25a2d0e187596c638121ed948 -Clang.v17.0.6+4.x86_64-linux-musl-cxx11-llvm_version+17.asserts.tar.gz/md5/71a77a339451b9d49858ecbb11119efd -Clang.v17.0.6+4.x86_64-linux-musl-cxx11-llvm_version+17.asserts.tar.gz/sha512/49c3aa8c8580969750ea6d61fd69e98d1daf47b9578cf3372febd2df79542e22940a24d23ce16dee20e4bbc4becb9340f820d3d45f879fbc5209f3f9699ffe2f -Clang.v17.0.6+4.x86_64-linux-musl-cxx11-llvm_version+17.tar.gz/md5/6a6d68aaf9ba085c02ca1218cdce0246 -Clang.v17.0.6+4.x86_64-linux-musl-cxx11-llvm_version+17.tar.gz/sha512/fcfbc12cb248021b4f8b9bcd7a21cf695b0bbb3983564a9602e6a23f83ef1b5d884927ae7b46ab5e3752a18d5346fc0b52a160ea18af1c9ee28870b470b4591f -Clang.v17.0.6+4.x86_64-unknown-freebsd-llvm_version+17.asserts.tar.gz/md5/e451f3326c665c8dbdb41ffa2b6362e7 -Clang.v17.0.6+4.x86_64-unknown-freebsd-llvm_version+17.asserts.tar.gz/sha512/d2b2f812dcd0d9d7602f37bbb629a8573be8e1d97e40efc51fe4676d6fbe69c21aa1943b6fc7172e788d3b3d2fd9d02fc3279838fad70434caf3a9e427006336 -Clang.v17.0.6+4.x86_64-unknown-freebsd-llvm_version+17.tar.gz/md5/995abd90c834cadde6f272e097ae51e0 -Clang.v17.0.6+4.x86_64-unknown-freebsd-llvm_version+17.tar.gz/sha512/f8f2d4ef5e2fac7d5e3b06ba76f7f54791820e15f0ab1bbd182a5e70709fc29085c73f5709cb45267671a849dd965e01683c6ced91281ef9d64f4750cf5d6151 -Clang.v17.0.6+4.x86_64-w64-mingw32-cxx03-llvm_version+17.asserts.tar.gz/md5/26143a5824a6564f69510f227acb6b1c -Clang.v17.0.6+4.x86_64-w64-mingw32-cxx03-llvm_version+17.asserts.tar.gz/sha512/1ce7c9cc3c9d04934f06a32d67f5c23f68cb26b917cf81c8e9844ae20eab4709110a4142d21b62b205c714363df463e63c2563011f432e2e0206731841798ea0 -Clang.v17.0.6+4.x86_64-w64-mingw32-cxx03-llvm_version+17.tar.gz/md5/06dbf7651fe7d8b021fc1ab6beb125c3 -Clang.v17.0.6+4.x86_64-w64-mingw32-cxx03-llvm_version+17.tar.gz/sha512/daddc731c54c13c0b2d665bb4360a400fec3246f6d756d5401a241cf6c9dcd2fb1df2f55c3559551ef9536d40067e9ae31753947756ef6210696b87856f831c2 -Clang.v17.0.6+4.x86_64-w64-mingw32-cxx11-llvm_version+17.asserts.tar.gz/md5/722fa85d203c5da1b4e28a1510bfa27a -Clang.v17.0.6+4.x86_64-w64-mingw32-cxx11-llvm_version+17.asserts.tar.gz/sha512/cf8d09192ad248c6603de813b22bcb61e72994d0d39cfc4260d6f6e1ebe69386313f924c5e3de3021ce2041bc41d8a022623bae5c8979fcf81649c85ee25c9f1 -Clang.v17.0.6+4.x86_64-w64-mingw32-cxx11-llvm_version+17.tar.gz/md5/85b8d93bdc92b4014d45f5dff6ba626e -Clang.v17.0.6+4.x86_64-w64-mingw32-cxx11-llvm_version+17.tar.gz/sha512/b1d66f9bcbaa3dc571fa8a1ca79f39f79ce4c7941bdd1a1fb7df2aae2c90960b9ffd7899237da1379e1898c18e2ffcc63eeefd20ba64550aca82167474981494 +Clang.v18.1.7+2.aarch64-apple-darwin-llvm_version+18.asserts.tar.gz/md5/ce3e582bcf2f92fdaf778339e8c51910 +Clang.v18.1.7+2.aarch64-apple-darwin-llvm_version+18.asserts.tar.gz/sha512/4f977e8f0912f52b9b4054089a53a05f60bf7ae352c39b2541e68fecf3c21969d6d1b85e40d71d61040b65f7c60a2c33c8d259734bc1d2ddf77392fc425025cb +Clang.v18.1.7+2.aarch64-apple-darwin-llvm_version+18.tar.gz/md5/1eda08774c2f9975de32bdce4ffc72bd +Clang.v18.1.7+2.aarch64-apple-darwin-llvm_version+18.tar.gz/sha512/c76ec1de9a25f4f8bd309336830cc07e1113b941ced12cb46976b24aebd4ab3d261c943dbc9cdfb34a01f27073af6f598dded31a4e03c62f229cd2e7d5982af6 +Clang.v18.1.7+2.aarch64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/2817b0eeb83eff4e1f580729e02564ab +Clang.v18.1.7+2.aarch64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/88242559299836c7a7b7d3a216353fc6880a587a839793ed71d6d053318d6e2071ff218587a082f2b5dd9fb2b0952b4c60e62030d707435607303708bb1e6d81 +Clang.v18.1.7+2.aarch64-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/d3f92998b7cc35a507cb1071baae8b02 +Clang.v18.1.7+2.aarch64-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/be22296623f604927e2e815a1cc149addda6d567270a50b2cdf77fe5b09f74313210a1ca7b1b3194592da23490ba1ccfdab9f520ce7219989e646f12208e418a +Clang.v18.1.7+2.aarch64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/716300acfdee4415f1afa3b5571b102b +Clang.v18.1.7+2.aarch64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/b97efb3c461ea7d2736a3a8bb6b6b5c99f02df9a095f11291319c629d44f1fb934b124d38af6be3e5cc7103c6f85793d7f185c607383461de5d0c846560a1d1b +Clang.v18.1.7+2.aarch64-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/034f44b2fc61791234d9580402002fb2 +Clang.v18.1.7+2.aarch64-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/0b4ff55afcec0b1e8fbd09fab57de8b44d5ded360d3b53132c7a7df8d3a3b83a495bf6e0c706784e678c6de46be3a72e8bfe562c7f8dfad90b82880849625e35 +Clang.v18.1.7+2.aarch64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/md5/54211070d63a2afac6350d06442cb145 +Clang.v18.1.7+2.aarch64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/sha512/a58f8afe9a20f202cf3956f758dc13a10be240d78877a02cd006d7e972751ed65623eef7e92a7256d9ed9157d6e277302f93b58f583d86d386ed4945f3c7d875 +Clang.v18.1.7+2.aarch64-linux-musl-cxx03-llvm_version+18.tar.gz/md5/7084567b3637fe64088fdce357a255de +Clang.v18.1.7+2.aarch64-linux-musl-cxx03-llvm_version+18.tar.gz/sha512/77ae83e159a814a7117cc859a0b2aa7a5d41f983d45b7eb1ce2fd2e93f8733ee067ac8c9fad9d5af90f852b8802043ef39c29b44430b2594892e57b61ccb680b +Clang.v18.1.7+2.aarch64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/md5/9e294d16a6e1c2c76c03f32cbbbfbe23 +Clang.v18.1.7+2.aarch64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/sha512/b8f83542b51f5cf953f6baed185550394744a8466307ee08525bf18a651fcecd7daafb98e75a0866b0e9a95a524e8940be7ae1878ba80d856182dcb7f7d2254e +Clang.v18.1.7+2.aarch64-linux-musl-cxx11-llvm_version+18.tar.gz/md5/70a41c2ffd55d2d87a7b8728287eb9fd +Clang.v18.1.7+2.aarch64-linux-musl-cxx11-llvm_version+18.tar.gz/sha512/44bb3dea7227ee991b2666c43a88613d5b5d382eb560b5ad1f1184d38680c85a2ef961bac6ad71c2b920702c1ec6e09296198e7ff5e2929f4ba7839e55896e3f +Clang.v18.1.7+2.armv6l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/95ee1406f8575898eb52e2c86ae18992 +Clang.v18.1.7+2.armv6l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/4da66e4d397491836b3e539258844346fe50bff41e6c0628cbb5c0eac76147bd91d1720cec1523452efdb063adf6ef8792dc278244e1f8e194ef60a180442c56 +Clang.v18.1.7+2.armv6l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/md5/6c4e4e892b54ce81d73a8598728083e3 +Clang.v18.1.7+2.armv6l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/sha512/53d08fd8b6782867cfa6ce001b14a2fde38bc9ffc85c7e148aebf59dd9c1c535b54eaea816c39fcff42abc456c1047ed13d688917302bcc5a281abe368bd29bb +Clang.v18.1.7+2.armv6l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/5acc5853111bcd529eeb06ea31b329e5 +Clang.v18.1.7+2.armv6l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/b1794f7cdfba838a7e43de8f66700ae44fd16d8f06300e8ab955044ae9bc96110c5ea72691841cd3787cdc93dfb91c6b257702c20390689a8d1b45a994db2fd8 +Clang.v18.1.7+2.armv6l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/md5/c4de50252e557fb126360001ddae6a97 +Clang.v18.1.7+2.armv6l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/sha512/9343a7272c76d5341bb49273ff8d43bed09ad99b2879ec51cfb8946174181b286af82d85e2d3a13a375c7e7859e51e4a4f06031a6a3fe7e540700cfc6a795741 +Clang.v18.1.7+2.armv6l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/af301478b20e56cb7fa1160cda2573a2 +Clang.v18.1.7+2.armv6l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/8822c58df101c239221fead6fb523e677da04a065b42849a2e6ffff03dfd81e07f162a9bbdd29490ad9c0e0a33d362eec46608b9e6e42dfb4889da1c22191c91 +Clang.v18.1.7+2.armv6l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/md5/901d2808599d5ac5ac7b5ca4bc39833d +Clang.v18.1.7+2.armv6l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/sha512/820756cad00b1fe927801a253bd3077709c2b067ae79f9e1812f3cc9e85a0b7ac2ce1534031b7c6f7bda3364b7173c1c508e7c7d316920fb9bb901c16c1b18c7 +Clang.v18.1.7+2.armv6l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/d1f368604084e907c382aaf00efe452c +Clang.v18.1.7+2.armv6l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/523b25f6b79e222eb65b5f4cd8f23b0d2c8b25b29af0df88efe45546ea57c7dabd88baef454fa0b76342d8d364739107271f25d3504380fdec5c9d225fcc2521 +Clang.v18.1.7+2.armv6l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/md5/e57c116b2ad1cf32307eb4e600ac80be +Clang.v18.1.7+2.armv6l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/sha512/63366b983c7aac9fe1246b25432b2200c8316f569f6930eb12de3c867f448ffccb8756d418f92eae7751d4c9ce6c42cee38237e429b81530819684fd5150c93a +Clang.v18.1.7+2.armv7l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/645929ce42276db10ab79184a60cd6e3 +Clang.v18.1.7+2.armv7l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/65555ed26d9bd670b8363e5dad949822c2bf0e141a5418e1dc30c3f8a4733dd050620e40be2e7552c2551ecb30d4ef3e8f74cb240f1d441a9720a25f5a3bcaa7 +Clang.v18.1.7+2.armv7l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/md5/8424c6c6318dfa7bebeac33917b29453 +Clang.v18.1.7+2.armv7l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/sha512/6cf90c253f6b22358c2389a2347af2febd010117b22de0cc91ad713b8c8224627398004567c96b673650212eb5bd40bb97b9a637d46ddfeb3c72388d83445017 +Clang.v18.1.7+2.armv7l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/ea8151dc1dc32befe579c7f9d7f13898 +Clang.v18.1.7+2.armv7l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/ed518423e9ec35afd7983471cf9ff1e971b840f637f34e0f62a1f6c7379ea59d4dafbeb9a311d39761733ecc98c0318ce3d8883298f8998e9c741441c7c9616b +Clang.v18.1.7+2.armv7l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/md5/70ed39b13bcb0435fee63bc30ae25a39 +Clang.v18.1.7+2.armv7l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/sha512/b2afa383346875514c62129c2991b3604c4fd3d507ecf4fc4244dec81d08b30218f5aa03dc4977185c2c9fb2d08848ddd373e448883ab472e5221ae5bf285c99 +Clang.v18.1.7+2.armv7l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/e6798835128f663f0c837aed4463e34b +Clang.v18.1.7+2.armv7l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/c99856e16bd42ff967479e2c89690ea41268f1d1f868e2628482eafdfa53a0d69ed7c21ecc68ff0859eef07d9fe02f4844fad5f13df26cee6cea3a4254446096 +Clang.v18.1.7+2.armv7l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/md5/92c1bd54b0474244e35c51952966a55b +Clang.v18.1.7+2.armv7l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/sha512/2d7c3b60ba8b11cf903bc5ea720193852027cbe61ea0c8d6fac70be8f97691da3d36663aac6e61b68185dd83b42d09ad61dea973d9390271210d690295e4902c +Clang.v18.1.7+2.armv7l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/c495d594f8ce1f701d1bab54d0b60521 +Clang.v18.1.7+2.armv7l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/0261bf45403daccf236723383341dc791e9cb3b291bde97812378d85aed785f083d5deea3bf806480a04ef1b972b00dccfd0537e43532a066c64733b817c3d77 +Clang.v18.1.7+2.armv7l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/md5/41541de24d625271bdd5fad867b8eb0c +Clang.v18.1.7+2.armv7l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/sha512/595226ad7ef75ab8ae03adb456b4ee9e884e9554c720b6c4ecbc38c75d446ddba7898be94630673074f09f40c6dc3e18fea9cee5a91b8b0e4727d20a180f670c +Clang.v18.1.7+2.i686-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/8bd8ca0436611e78882939067f6277f7 +Clang.v18.1.7+2.i686-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/27c7b06e93fb0fb516b1b240e0df6c95e8bad6aea04d637ba065c6fafd087bfa94d9136afd39273c8d82d9c467395dcbd7b16f6a4b829acb0c0d4a5677676a5b +Clang.v18.1.7+2.i686-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/424bfbd7b69ddf7b1199afaacde3e028 +Clang.v18.1.7+2.i686-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/9c48d949309aef6ee39371ff39a4f12c31bf3f25ddd288b317b2a17a803db73850cba2886598a1d10c4c154d511a4b79958d1acc012e92491a63f3925c522873 +Clang.v18.1.7+2.i686-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/6b0b3e045ad64ecdc9848898f30d5f34 +Clang.v18.1.7+2.i686-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/6c0f4bdabbbc94fc9e1fedc138b0bce99d383e380ae7222fb70f5935f17701d549f6486956c8a21731061e4bf60bbc52794f6ce6858b4d2adb89bf80f88795c0 +Clang.v18.1.7+2.i686-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/3b7a461ebf957756aeb2a2455b0a298c +Clang.v18.1.7+2.i686-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/74641a3636dd58c69415b19f0cb1de444215e22cfa9f0268fd549b5c53b206811d8beecdeb9692285613468d9a0569e836d225fb8361218438346914f6282839 +Clang.v18.1.7+2.i686-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/md5/5e7b9ad5fc3af3bfdf262687cd248dfa +Clang.v18.1.7+2.i686-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/sha512/c54835fdf8e3e442b7c774d445c2f13c5dd8b3224f4ae165e72cc893ee5453d0112a9ca6d543b17f2c02a89471e2cff7cf022dc4c8188a5df25d101dd0f954b9 +Clang.v18.1.7+2.i686-w64-mingw32-cxx03-llvm_version+18.tar.gz/md5/3204bd8074d42920a6707cc8624c0dfe +Clang.v18.1.7+2.i686-w64-mingw32-cxx03-llvm_version+18.tar.gz/sha512/74b26c4556ca18645cc15647d8abdbd46fb94c75169934af885e5773a880c066b2ff221402fdb4a53417b2c97ce589783f7fae6a8d56ee89cc1f70577b02b2a1 +Clang.v18.1.7+2.i686-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/md5/7922c04964e0c1a5b44e95480290930d +Clang.v18.1.7+2.i686-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/sha512/4f0d675c1b85dc3e5007a62a7cfea412ca432d1276a259db3ed5a1bf0f33d6c555f16010de717a62e0e065e7c1dbaa66c281815eb9629d2b6c720b152820e582 +Clang.v18.1.7+2.i686-w64-mingw32-cxx11-llvm_version+18.tar.gz/md5/e023eba0ea0a327f53013d5e4d50d0cb +Clang.v18.1.7+2.i686-w64-mingw32-cxx11-llvm_version+18.tar.gz/sha512/9fbdebce9c7375a20d1cd10e39a0c26b131af686cb5771034a6afc6cab08855e0cada2add616c01394424383333950d0dde9c55a9477fa139cf0ca3fc438b229 +Clang.v18.1.7+2.powerpc64le-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/a6c7d64ede931fb19e066a1c191e2f6d +Clang.v18.1.7+2.powerpc64le-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/1a085a4ea1efb910f2b529f3c0e51be4a5e31debbefd00ceefeddc352b36bea6d0de5a06ea7d509098d16416b536ffed3da8485feefad7a2f11b1bc148a0c8c2 +Clang.v18.1.7+2.powerpc64le-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/692af94ca3e5c3d229cbb459e266aadf +Clang.v18.1.7+2.powerpc64le-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/b27f05cfb0ada89cefc5a6f6527583b6b43d03525954d5b1ad1c807712efdb8750ea558a230b587a0c0d9e77c54d9f8978cc2f3884653808c7409eab1b32a055 +Clang.v18.1.7+2.powerpc64le-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/3b59b6aa4b18b5dbbc632811f2ffa270 +Clang.v18.1.7+2.powerpc64le-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/f8c4b593f969c723ff1931c4875ed52497d83d74b94121890e10c9fcca5f6bddc5067555dee9949e61e426586ae3e568375fc44f318a07b70571ee34fdf7032c +Clang.v18.1.7+2.powerpc64le-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/bc4be32ad57b13c3dabc80684a176ba7 +Clang.v18.1.7+2.powerpc64le-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/19a8346547b6c6adc2a9156e4b913b20137593752efa3648ad532b08de67cf015bba1eb023204755f48904c3381a3665c6c54fc8233c50e887a22ceebc652303 +Clang.v18.1.7+2.x86_64-apple-darwin-llvm_version+18.asserts.tar.gz/md5/05f37d069c7d59ec245d961d0928cb37 +Clang.v18.1.7+2.x86_64-apple-darwin-llvm_version+18.asserts.tar.gz/sha512/3b0956fe770fd9230319bfcaefab4922f9aee3df3e8516edf81cb7d322132ee9ab899af4464c75b1042aa99e3bcb07ede6de5646bba2a57995fc2eb32d4d0861 +Clang.v18.1.7+2.x86_64-apple-darwin-llvm_version+18.tar.gz/md5/0304434211ff4101a148fcc0c96455d4 +Clang.v18.1.7+2.x86_64-apple-darwin-llvm_version+18.tar.gz/sha512/a033dc589fc95e63547b7ca82964116bec33ad6e78ac131934d4bb16988756d36c24d74761ca93b0e47dada1f3d2a63071cb3721ddb9af457cbeb164fe5f0f54 +Clang.v18.1.7+2.x86_64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/4e5d1064d90f24d57d63f08b61baaab5 +Clang.v18.1.7+2.x86_64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/cbfbe8b6f2be80e59b69d25d6af901ccb4807b12180208b69afa7223dd7d5249255265bc319c9402a1b0d1f0995940e3e72d7ecf1009f60d83021f8d35626a46 +Clang.v18.1.7+2.x86_64-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/22fead15b4c45398ca869821d04ce015 +Clang.v18.1.7+2.x86_64-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/2ee7a7d3f293f7b63c89bbe3b541722c502a840883804ffe272848f4ac99b7a8ed350ebe92ec434dfdf03d1f4a5531c1367859f4a4603c98325abe5a0ad71177 +Clang.v18.1.7+2.x86_64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/46dd01b10377cc3d45c6a42cac0a07e5 +Clang.v18.1.7+2.x86_64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/957677ce4251938d0c5e066448762b38a21bcce5ed424072ccd58085167d61b7e45a88fe32375f6bbd43dfb579b65a9afc09a886a650fc634a8fb9c81f27c9e3 +Clang.v18.1.7+2.x86_64-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/bd9a61ea186a39162201341f0739fe84 +Clang.v18.1.7+2.x86_64-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/7a06d2a9ef20e88daa00d627d482ebbb6bf7223219d8b2a24aa60ac9eda24649d206b093d5bdb88b65c1e2b0d1ba0ad7dd927697e2bbac65bc9b42f9d14ad0d9 +Clang.v18.1.7+2.x86_64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/md5/60c98c6cc7d4446fb52b7585bc8709f3 +Clang.v18.1.7+2.x86_64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/sha512/4d55464b4499a45f774e1000a8b015326d114103a3d348fb263367e5506ca6659444ea6ee2767712903757e83939cd446aff6fe2351438b644f0057053422b58 +Clang.v18.1.7+2.x86_64-linux-musl-cxx03-llvm_version+18.tar.gz/md5/90a512d1881c4af1f1abfd5e90e37356 +Clang.v18.1.7+2.x86_64-linux-musl-cxx03-llvm_version+18.tar.gz/sha512/62d6d855aebd49f132d6470c7b0d5a0b965c6489b025046c1ea73fc53336030d6c5b4c867523a9206821f7fcf62fdb37ef0b7ff4b5eb04d07f40b65edd2c8e0f +Clang.v18.1.7+2.x86_64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/md5/c9eb9acb605d774db9636b82bf2e5f41 +Clang.v18.1.7+2.x86_64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/sha512/96e1440b3b0378edf8907d4cf779b1c53d63f6d00fa798efe1b6aaa289135aba8fd00a8d6f55d9678136e9e07d0c189293aec64f46e66788b938e1f8e1fc2199 +Clang.v18.1.7+2.x86_64-linux-musl-cxx11-llvm_version+18.tar.gz/md5/5837070450c81d44395468d8e3671dc7 +Clang.v18.1.7+2.x86_64-linux-musl-cxx11-llvm_version+18.tar.gz/sha512/0e8b674c0360f9586f03c7f5d0ffd5bc73dcde1e88eddf7d6360c1461adb8efffb104d8f454116a6a6cdc909973d0876745590b21009a9de56e12ce6e1c2e8fc +Clang.v18.1.7+2.x86_64-unknown-freebsd-llvm_version+18.asserts.tar.gz/md5/5c198d35df5cf6435f4f5ac91a78be01 +Clang.v18.1.7+2.x86_64-unknown-freebsd-llvm_version+18.asserts.tar.gz/sha512/9ba0a532f499933320145834aec2b57a70410bf67af649ed675f00aebfd59de7c80e6f5d19e7ad57029a573090e63c5eba4b42b498a374810b48c8668b50dcaa +Clang.v18.1.7+2.x86_64-unknown-freebsd-llvm_version+18.tar.gz/md5/8ac88c856d946e29d1121426de44e6bc +Clang.v18.1.7+2.x86_64-unknown-freebsd-llvm_version+18.tar.gz/sha512/94af63ad3fb17d9c07f5256e2d474effc0e3d5ef66f4a9f3ffeb9bdd8f1577c35e4d0aceb8b4746ab857d8f164141790ed494b7f687e644e040d2f3820f9e1fe +Clang.v18.1.7+2.x86_64-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/md5/b4be546ff44019cf46d3250dd9a4321f +Clang.v18.1.7+2.x86_64-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/sha512/7ce5e4d68e18021392355359f59931219eeec3be4edd01f7a18b7bee499b589414bcea73820ee38dbc3b5ab12d912a93374b4a616b10ba491f5d41b6b33f3d9e +Clang.v18.1.7+2.x86_64-w64-mingw32-cxx03-llvm_version+18.tar.gz/md5/4616c348320d8704215d58c7268de6d7 +Clang.v18.1.7+2.x86_64-w64-mingw32-cxx03-llvm_version+18.tar.gz/sha512/b4c21147ed21d41321e04b092d47f99338c6ac7d50b8328ceb8ae26d6382955cbcd655dddd39f0de3d3c36a5fda7084a33272aad9f6cd9585c87fee68be73a68 +Clang.v18.1.7+2.x86_64-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/md5/bf9cf2efb938b68ac7e1560c464f9051 +Clang.v18.1.7+2.x86_64-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/sha512/ca29438393d393912571a96ce59bdaadcacbb329342c42a0de0e8d8ab52f69d4e6966822c0743d99b1a277c8715c1f72ddd490b781b45bd691df2c137ed42a1d +Clang.v18.1.7+2.x86_64-w64-mingw32-cxx11-llvm_version+18.tar.gz/md5/94138893eaaa99f37354317bc13cf7e0 +Clang.v18.1.7+2.x86_64-w64-mingw32-cxx11-llvm_version+18.tar.gz/sha512/1b03d8d4e407372875667f25f74abdaac9be0b81c6229dc1c4c1714589efde6b1f8c76302a2545b103ee4f9812fa78f9e06e5d5bb5bc3903ce579328899faa2f diff --git a/deps/checksums/lld b/deps/checksums/lld index 9238ed622c27f..cdcae063f68ff 100644 --- a/deps/checksums/lld +++ b/deps/checksums/lld @@ -1,108 +1,108 @@ -LLD.v17.0.6+4.aarch64-apple-darwin-llvm_version+17.asserts.tar.gz/md5/3144fe910aa5fa308a2a2ca86820541f -LLD.v17.0.6+4.aarch64-apple-darwin-llvm_version+17.asserts.tar.gz/sha512/6b60bac8ac870c6e0f2f615ee92599c863e388bb9a654ce7dc6b037e6f7ba77b4401f88471dcdb2c8418775a833a10b010bd932a61c4264b032f5bf42642559f -LLD.v17.0.6+4.aarch64-apple-darwin-llvm_version+17.tar.gz/md5/f65548e0c2c455550635d2821822e97f -LLD.v17.0.6+4.aarch64-apple-darwin-llvm_version+17.tar.gz/sha512/52862c78a5bd6a33848ce33c79eabad854a5cb86487ff755160f3a7c89ceafcc24773495ced5d7d25e952b7a7147969a890de6806845996a0dcb3ecd8c1ce1cf -LLD.v17.0.6+4.aarch64-linux-gnu-cxx03-llvm_version+17.asserts.tar.gz/md5/e4b46d1b3397fbc876db8f0a15745f3c -LLD.v17.0.6+4.aarch64-linux-gnu-cxx03-llvm_version+17.asserts.tar.gz/sha512/831ae6748e0c18e4be6a732dee56bfc3b84383e7c607828f72ba798db0bc1f61e9379edb904cfb992455ab5ecc6d4ea7dae4bd8eba481a857afe6439fdb333ac -LLD.v17.0.6+4.aarch64-linux-gnu-cxx03-llvm_version+17.tar.gz/md5/16d60350522a797fac1fc3ba47609d7c -LLD.v17.0.6+4.aarch64-linux-gnu-cxx03-llvm_version+17.tar.gz/sha512/6d457e4de4a896bc4d8742a9c7a09c334f9f0fee1fd5e93133128889c326cb3891d7b7f774a01d1936717639bc5e84b7a3d6d39866cd6e689de78cecb5934f80 -LLD.v17.0.6+4.aarch64-linux-gnu-cxx11-llvm_version+17.asserts.tar.gz/md5/f55f1eca81cc38584c94a8db9d53b53f -LLD.v17.0.6+4.aarch64-linux-gnu-cxx11-llvm_version+17.asserts.tar.gz/sha512/70abc3cfdf7c94ba3cbc26aaee3328e28a5e19136bd659b619a6240d64d50029f94ae36e5ca4359caf1db79e13e6283cfd7b806e96fc3245586970edaf678a0b -LLD.v17.0.6+4.aarch64-linux-gnu-cxx11-llvm_version+17.tar.gz/md5/e7370d074ce08d8de4aa6a34ba7f4efb -LLD.v17.0.6+4.aarch64-linux-gnu-cxx11-llvm_version+17.tar.gz/sha512/5491fdf2d478abacad107a7de626d0f70388568b8f50732a91f30a93bc79a683d7acfb37a2ee9dda39f860fd9af144b322400fa0152f52041fec13a4ac01f511 -LLD.v17.0.6+4.aarch64-linux-musl-cxx03-llvm_version+17.asserts.tar.gz/md5/f75f229860bbaaf61d8ab8d89745d5b2 -LLD.v17.0.6+4.aarch64-linux-musl-cxx03-llvm_version+17.asserts.tar.gz/sha512/046bd2cbf12a3d381821f87800635957bcb0bf37d55bf4a8046ca39fc652c2b98ba0f8497216f6c580b738db319932e8610c6215b020e993bffd129f730a4d9d -LLD.v17.0.6+4.aarch64-linux-musl-cxx03-llvm_version+17.tar.gz/md5/21c591ea3725c02c5cc1ba861b435966 -LLD.v17.0.6+4.aarch64-linux-musl-cxx03-llvm_version+17.tar.gz/sha512/600f590486acf10dbde10dcbfa728bd53152ee7134bbb68cc15f724017f8b5e50102a286ae7a836c197c974d34078ad8e8988cf97ef032ab97d9aeab96ae9994 -LLD.v17.0.6+4.aarch64-linux-musl-cxx11-llvm_version+17.asserts.tar.gz/md5/89770e2c5fbd1f36775081f37e8374db -LLD.v17.0.6+4.aarch64-linux-musl-cxx11-llvm_version+17.asserts.tar.gz/sha512/650e5fcac1f00c2ed576d9232df46325dfa2e283976ec84a7cc12c8127d532e3b4d758a736e5ca1efb5a09833f0369ab44b277469fb49d50ee14ddd9ebcf6a8d -LLD.v17.0.6+4.aarch64-linux-musl-cxx11-llvm_version+17.tar.gz/md5/4e9b983fadd5fec3a2b76698fd24bbb4 -LLD.v17.0.6+4.aarch64-linux-musl-cxx11-llvm_version+17.tar.gz/sha512/058bcf4a9cee81287d1f19e9bfe5a8d16ad7955fdf175ad0f7be6fb6fcb9177674b08a8fdc98b4365324e3c754c4b957aec24daa8c135974a2f2737a6054454b -LLD.v17.0.6+4.armv6l-linux-gnueabihf-cxx03-llvm_version+17.asserts.tar.gz/md5/3cf9661e272471213ed27d70a28245d5 -LLD.v17.0.6+4.armv6l-linux-gnueabihf-cxx03-llvm_version+17.asserts.tar.gz/sha512/4c2b7d02bfc73e2c36469b249bbdb9e6e695b47a464a71d5eca495fbd21fae35bbb260262771246f995ccb83ba1d89a5946d76cfb49de327f659d467ef3b2d93 -LLD.v17.0.6+4.armv6l-linux-gnueabihf-cxx03-llvm_version+17.tar.gz/md5/432800b0bd1fa328c929f24765cc32cd -LLD.v17.0.6+4.armv6l-linux-gnueabihf-cxx03-llvm_version+17.tar.gz/sha512/338053e5aa25b4cffb10ab2064b5e1e75ca628cfe006933bc125421406a00a1b84386a4ad027fca75211bba9860cdcf0d1c1e992752603ada97442d97cf17f20 -LLD.v17.0.6+4.armv6l-linux-gnueabihf-cxx11-llvm_version+17.asserts.tar.gz/md5/067465123a0343a6c9d8d9cec1a6c3ee -LLD.v17.0.6+4.armv6l-linux-gnueabihf-cxx11-llvm_version+17.asserts.tar.gz/sha512/895bc632e732086ac7676e9596c7a6ebc5f807fb49bd2cb542252aba76aa4faac8e7bc423681e3dd1556bac5fe5754a5e09490e2f97e40e0551263d021987290 -LLD.v17.0.6+4.armv6l-linux-gnueabihf-cxx11-llvm_version+17.tar.gz/md5/27f10a51c07df6550e9945913b8f40be -LLD.v17.0.6+4.armv6l-linux-gnueabihf-cxx11-llvm_version+17.tar.gz/sha512/fc8fb0dba3aefa19098c3065cc0e83edabf9a3052691c6b3fac229c0b0bd605fa7062ad4f117220e51a6f6c15a0a6385cbdc8a2d8a0f46f96cd637fa134229de -LLD.v17.0.6+4.armv6l-linux-musleabihf-cxx03-llvm_version+17.asserts.tar.gz/md5/5d5719e989de5cffc156955875e8ccc8 -LLD.v17.0.6+4.armv6l-linux-musleabihf-cxx03-llvm_version+17.asserts.tar.gz/sha512/71ef0800633546b4945d460f51ee9e042bfcf4d0caecbd658033199ac82bcade9efe9749998396d42345c914621f658b3d7285c849f554d369acba8c7c75ed2a -LLD.v17.0.6+4.armv6l-linux-musleabihf-cxx03-llvm_version+17.tar.gz/md5/416ed355013ac094d39cc8bd6d573917 -LLD.v17.0.6+4.armv6l-linux-musleabihf-cxx03-llvm_version+17.tar.gz/sha512/a8d74edbf881b4f4212f22c01bc37e82dcbbe0e9399823604ed1ee78ab33a5cbac5e13933348878cd7cbac0077547af27cce80becbc5a2ebc6329306c86f45ba -LLD.v17.0.6+4.armv6l-linux-musleabihf-cxx11-llvm_version+17.asserts.tar.gz/md5/68a609cb681b1fa2d7e8ad87ca31020e -LLD.v17.0.6+4.armv6l-linux-musleabihf-cxx11-llvm_version+17.asserts.tar.gz/sha512/6cba7cec86f914790194652fff53996458db01d26b322d2e76321273d425605d706d631141f2ae675bbc44712f3761fa2a90874de13a280fc2cdcc98eec6e0a3 -LLD.v17.0.6+4.armv6l-linux-musleabihf-cxx11-llvm_version+17.tar.gz/md5/a3e3ae95dc0227f6a1c596b42fd5d6dd -LLD.v17.0.6+4.armv6l-linux-musleabihf-cxx11-llvm_version+17.tar.gz/sha512/e8a7e21ef3726353d15d1406cb76ce2e79de7d59244ee9c2dba6f2ca9255472dea28d9aee68d4d806f0a291b9293a3e3548f791c06b3461234efa36eac1ed356 -LLD.v17.0.6+4.armv7l-linux-gnueabihf-cxx03-llvm_version+17.asserts.tar.gz/md5/1e43637c4e6ce02d7b2de3713c028067 -LLD.v17.0.6+4.armv7l-linux-gnueabihf-cxx03-llvm_version+17.asserts.tar.gz/sha512/820eee9280781fffe5bab8464294199389de9a6000cbdb2e3f8ae3d2c474ee176442b128436cc6edb414eda06ebbccebc4277b3d0b6b4a7a0d4d232e18593eb8 -LLD.v17.0.6+4.armv7l-linux-gnueabihf-cxx03-llvm_version+17.tar.gz/md5/a61866ddb1da3130bc2c58426aee6b05 -LLD.v17.0.6+4.armv7l-linux-gnueabihf-cxx03-llvm_version+17.tar.gz/sha512/a193e68d3ffd1794d0107d4f003ba0ad5f5e3e72fcad1b6652c5487cbad57d9357311c8f14a8a40c2c7384042d768c86ba17f0ee5fbc3439435224273ed2cd3e -LLD.v17.0.6+4.armv7l-linux-gnueabihf-cxx11-llvm_version+17.asserts.tar.gz/md5/e72ad283df0a290f1eab61a2037031ad -LLD.v17.0.6+4.armv7l-linux-gnueabihf-cxx11-llvm_version+17.asserts.tar.gz/sha512/99d04f3f27fde19d1e61821dbc3d1748e6687899e46206c99442fa9b7086f8ade1199c67f16cfc5be40bbfe37da602508441a5269ea741186a79ea1d221a58c6 -LLD.v17.0.6+4.armv7l-linux-gnueabihf-cxx11-llvm_version+17.tar.gz/md5/bd08e53b82b168fbab8d97e9460ab9b0 -LLD.v17.0.6+4.armv7l-linux-gnueabihf-cxx11-llvm_version+17.tar.gz/sha512/408557a99ba6c794eb8de0b0dcca04662a079f6af2e7a663075b8f18eb422006235650eadf32c3abde662f12f87019cd73c5ae759207dc11101d3f1c3b8e2d11 -LLD.v17.0.6+4.armv7l-linux-musleabihf-cxx03-llvm_version+17.asserts.tar.gz/md5/df3bb4b61144f94e9ca0ffad461fa69f -LLD.v17.0.6+4.armv7l-linux-musleabihf-cxx03-llvm_version+17.asserts.tar.gz/sha512/e9ca992cd148026fccfe47b1e8df1bb8b60e7e44341d664a3447c06030dccf2a95ffd281b9c7346524cf87daf4e72ef7defcc1233a3b5adc228adb5b20d5d911 -LLD.v17.0.6+4.armv7l-linux-musleabihf-cxx03-llvm_version+17.tar.gz/md5/3b6879510e198560d65d29f6cf238b5b -LLD.v17.0.6+4.armv7l-linux-musleabihf-cxx03-llvm_version+17.tar.gz/sha512/75a8e70ec5071fd41031ca96e1560f4471b6e0c45ac361d10f11e41c9e63ed41e850170f5b97cf305d0e28ac695b8a86d8d777c7a3582f6aaa7953c00a666fef -LLD.v17.0.6+4.armv7l-linux-musleabihf-cxx11-llvm_version+17.asserts.tar.gz/md5/03eca3b921064050532b59049d2da878 -LLD.v17.0.6+4.armv7l-linux-musleabihf-cxx11-llvm_version+17.asserts.tar.gz/sha512/b7ee2af9440fdabe72005b84e05d05c28f2736135df63859f8d6ef7a10f622122d3f2d0a393ddcb39bde21ea8fbcba4a99a46b5568e42dbff2a505a5cda79e94 -LLD.v17.0.6+4.armv7l-linux-musleabihf-cxx11-llvm_version+17.tar.gz/md5/cf9ce84e5631259776238a11c3528901 -LLD.v17.0.6+4.armv7l-linux-musleabihf-cxx11-llvm_version+17.tar.gz/sha512/b64f0b0e2b3180b569528479265f15ba2e44523dc7103af3daf82ef6b9087c2859bc378d51abf44ba10c6e10a9aac4498b43797d59ef3423de1f652beaf8b6a9 -LLD.v17.0.6+4.i686-linux-gnu-cxx03-llvm_version+17.asserts.tar.gz/md5/a85df5a842c1ad1e9db959fe8fcc39fc -LLD.v17.0.6+4.i686-linux-gnu-cxx03-llvm_version+17.asserts.tar.gz/sha512/9f037dad3faead898854235ed48804607e19a68e4a34a28e1ea09258bda9b06c1be88de4595bb50b43234e438353db00f47dacfa0754d88e8fce01b637808f47 -LLD.v17.0.6+4.i686-linux-gnu-cxx03-llvm_version+17.tar.gz/md5/46191b2a25020871c8c183d6f62ad477 -LLD.v17.0.6+4.i686-linux-gnu-cxx03-llvm_version+17.tar.gz/sha512/aefc623430f79050ef367edc394c72a09bfb4ec39c6ae4e31775d378d1169432695be1fef5bd93737502465363571c695f7a0a7bbcc78d78c8689a0a6b0e280a -LLD.v17.0.6+4.i686-linux-gnu-cxx11-llvm_version+17.asserts.tar.gz/md5/5f034672f90e88a30ced0ffa0880e8af -LLD.v17.0.6+4.i686-linux-gnu-cxx11-llvm_version+17.asserts.tar.gz/sha512/fc8a6fe2f4e1a6ccca3744a4cc51be62ad2c849e9ae942e9c0452aada0303e95b376b55c951e8ffc22b65e391bbb182c977c979a8c50b50c1426cf84ca8073e4 -LLD.v17.0.6+4.i686-linux-gnu-cxx11-llvm_version+17.tar.gz/md5/157f2faca0641168becea6b1493e4c36 -LLD.v17.0.6+4.i686-linux-gnu-cxx11-llvm_version+17.tar.gz/sha512/6981bebe07fba76f18e38f30aafcbf20325dd5a3f158ad732ce1d4f153839eb45966e707e0cdd008e8e739454f10f8dba0a372b0e67f7e753ed3e84ec47d4003 -LLD.v17.0.6+4.i686-w64-mingw32-cxx03-llvm_version+17.asserts.tar.gz/md5/de902268f693954466d62a154a2ac490 -LLD.v17.0.6+4.i686-w64-mingw32-cxx03-llvm_version+17.asserts.tar.gz/sha512/57eb929a0b21d047bf2a1da287fe2038fc9cd26bab43b013ad8794abaeb387a5be0eb7d4f9ece52171609d9b74f1aa743c6cdbdbc1eb78b425e42a1ffc862133 -LLD.v17.0.6+4.i686-w64-mingw32-cxx03-llvm_version+17.tar.gz/md5/d11bbc63ca2635836f5b95283f6f93ac -LLD.v17.0.6+4.i686-w64-mingw32-cxx03-llvm_version+17.tar.gz/sha512/e8b9c2383f71be7daa2afbb0a6dfd6487c832673b3272b2759e139299491374c2c3e8ff6db71c526dc0e71901fcf81fcf77db4fcb9351dc1dab0315389cb19b7 -LLD.v17.0.6+4.i686-w64-mingw32-cxx11-llvm_version+17.asserts.tar.gz/md5/8ad1aaa3ce1bd9b3aee584b6494ba6b7 -LLD.v17.0.6+4.i686-w64-mingw32-cxx11-llvm_version+17.asserts.tar.gz/sha512/411d563c9856cde0834b4f035551cf1b0cb0ed853365f312889c8d85ff6e52f5470e7e9af5146061516439ad109945caf651209153db1f6671a4cb31b69abfa1 -LLD.v17.0.6+4.i686-w64-mingw32-cxx11-llvm_version+17.tar.gz/md5/aeb833592bda8c92781a9417daac1c7f -LLD.v17.0.6+4.i686-w64-mingw32-cxx11-llvm_version+17.tar.gz/sha512/79134510ab99d8478b80a9a14dafaa818320b9f823c024260b6f8a82ea7ed406424f35fc9882e4590a98565098a949f8ad01fe03aea2b8146aa22827a7dd710a -LLD.v17.0.6+4.powerpc64le-linux-gnu-cxx03-llvm_version+17.asserts.tar.gz/md5/db979fa556737823f4629c1d19d45adb -LLD.v17.0.6+4.powerpc64le-linux-gnu-cxx03-llvm_version+17.asserts.tar.gz/sha512/1790dd2098a07a31d3e3057257da0bb9d54dd71ee713569f9d15d35895feb143e22435eb1581d72922ff09ac5b733e0a3053aaeb2f31483e4441d7ee12bdffb9 -LLD.v17.0.6+4.powerpc64le-linux-gnu-cxx03-llvm_version+17.tar.gz/md5/63811a8ee9ec2915aafbff884e8ceef5 -LLD.v17.0.6+4.powerpc64le-linux-gnu-cxx03-llvm_version+17.tar.gz/sha512/b8f6400246382ab9288bbc0b4a50cbb9264a8c0e2e3e9695580577df8460b7de015a0628ac92bc54ffa14bc7c03c86ee1e52d032d423120d4c5c731b8ff07ae8 -LLD.v17.0.6+4.powerpc64le-linux-gnu-cxx11-llvm_version+17.asserts.tar.gz/md5/29e840a97982441b492bb6e9e30b369e -LLD.v17.0.6+4.powerpc64le-linux-gnu-cxx11-llvm_version+17.asserts.tar.gz/sha512/9a7477279f129c4c500694e78b0f587285e79adcad167da212e68c46a22c8456ef41c721d8332c7f101958cbc3ac055414fdec935e0980fe2d0d507b1bed736e -LLD.v17.0.6+4.powerpc64le-linux-gnu-cxx11-llvm_version+17.tar.gz/md5/97bfb5e23744e57e243a9b0d3fe4252b -LLD.v17.0.6+4.powerpc64le-linux-gnu-cxx11-llvm_version+17.tar.gz/sha512/394db3828de239afa47f6896f0014900146bf8e5ecb90014601aab86fa95dba434a78a8590ebc588d3a22b93ff6481587c7c3458dda751114a7a4b41e93a9a72 -LLD.v17.0.6+4.x86_64-apple-darwin-llvm_version+17.asserts.tar.gz/md5/9dd9fdabdb07a2d25270cd936e8ceb47 -LLD.v17.0.6+4.x86_64-apple-darwin-llvm_version+17.asserts.tar.gz/sha512/ffd59d483f969dee28e32166a8fe091a5ecfbb56d6c17d44c732f6f8608b14d29b4e3874d93ec2dc8563b9a4dabd61418836e6dd389aa0c38a779f527becf48a -LLD.v17.0.6+4.x86_64-apple-darwin-llvm_version+17.tar.gz/md5/574c37b28031d6332075b7ce3e4b8520 -LLD.v17.0.6+4.x86_64-apple-darwin-llvm_version+17.tar.gz/sha512/f09afd7098a56ef282ef364c59a2f91db51165d9ffbcbe63f70f68999c7bf67d6ee445dfde789be79c81e173db346702d983e03fe1ca51d2a2aa3cfd9b9e9e00 -LLD.v17.0.6+4.x86_64-linux-gnu-cxx03-llvm_version+17.asserts.tar.gz/md5/7bfb0b6c0ce4b271f3c0e7cfca20ce79 -LLD.v17.0.6+4.x86_64-linux-gnu-cxx03-llvm_version+17.asserts.tar.gz/sha512/66daf7d38f206d428e27227bc1218bb8fe32abdc50246ba6e49ec1494c48b5217697a69e3bff51b3510a4383e2ee743a8a0ad11aedbaa895ce8a56016b5d7693 -LLD.v17.0.6+4.x86_64-linux-gnu-cxx03-llvm_version+17.tar.gz/md5/f2666afb8179d10cabe3bf9e739a0e2f -LLD.v17.0.6+4.x86_64-linux-gnu-cxx03-llvm_version+17.tar.gz/sha512/fa59a23c4b24c444173454da85e77ae4a9aa73ab91b64efe7a6aabfe21c92e4909ec61b7b848d4b0190eb5e4ebaf0d55f8fc0d92cedc6ede76add230b8e6caa2 -LLD.v17.0.6+4.x86_64-linux-gnu-cxx11-llvm_version+17.asserts.tar.gz/md5/292e0354262b845ab359adf298aecc6e -LLD.v17.0.6+4.x86_64-linux-gnu-cxx11-llvm_version+17.asserts.tar.gz/sha512/654331656feb9c4fc27a5a06c838ffaa10ee7f74ee7eb98496e9d8d0882ac2416cb8662b5ac70968d6e8277ff675200a19c56989c120caa83170707c409e0cf1 -LLD.v17.0.6+4.x86_64-linux-gnu-cxx11-llvm_version+17.tar.gz/md5/c0b864d0d7a830627cf0feab502eec81 -LLD.v17.0.6+4.x86_64-linux-gnu-cxx11-llvm_version+17.tar.gz/sha512/72404a586c46b62b0317080b925ff5fd2ea99212df50fa6631bdd2f01bf805bbc8afb2e49bde16a4b8ee7896af4d58237326cb83aa064e98509e6f4f0fff46b1 -LLD.v17.0.6+4.x86_64-linux-musl-cxx03-llvm_version+17.asserts.tar.gz/md5/942a23af6c179c2715f2bba2048fa125 -LLD.v17.0.6+4.x86_64-linux-musl-cxx03-llvm_version+17.asserts.tar.gz/sha512/101a6ada3ed831dbb2f580185de732b90b81ce1b6ba544fc1ace40857fb471e61901a782f467a2077b2e34952997b8d04c841aa4e9f190e1488ce37c5f6ed32d -LLD.v17.0.6+4.x86_64-linux-musl-cxx03-llvm_version+17.tar.gz/md5/2f0aa6b5220213d549a2430a439094da -LLD.v17.0.6+4.x86_64-linux-musl-cxx03-llvm_version+17.tar.gz/sha512/180f0a520fc9089ce39ae8f032d7b415442c2ce6bc9a44bc427ae98000be55d0eba6278db1e89d45e3c79c907a75264bc8185cea088d002aa9557fe1b047b42b -LLD.v17.0.6+4.x86_64-linux-musl-cxx11-llvm_version+17.asserts.tar.gz/md5/6206795db1db9f9a86346ace421fa778 -LLD.v17.0.6+4.x86_64-linux-musl-cxx11-llvm_version+17.asserts.tar.gz/sha512/b86c57b2561cd8fbd4eb0158b0e3f4064cbc55936546da6dad794818eb93f51d80fac1dd094b2281ed6125416a205010e2edb801fc347db8d02d93fbc336d878 -LLD.v17.0.6+4.x86_64-linux-musl-cxx11-llvm_version+17.tar.gz/md5/e07b22829c2e8d4efdf8c41584a3cc67 -LLD.v17.0.6+4.x86_64-linux-musl-cxx11-llvm_version+17.tar.gz/sha512/4695f44b9a1b21684575f58dc66644907f7fd5250db42da2cfa55d90a4d5dbafc9cf37698750f8faac45ec38dff54eb382288052b7c95e82bfc60a10136ae5d2 -LLD.v17.0.6+4.x86_64-unknown-freebsd-llvm_version+17.asserts.tar.gz/md5/3e183403117e11f6c4b9059fb32e4acf -LLD.v17.0.6+4.x86_64-unknown-freebsd-llvm_version+17.asserts.tar.gz/sha512/34f6fb23cc234dee826a303a8ce3bf17ddf945c2ee9a75fca4f6c625379901d5fbc4d5d9006b63d95d982de852fa1594877cdbc9451b0ca04ecac72371d1647b -LLD.v17.0.6+4.x86_64-unknown-freebsd-llvm_version+17.tar.gz/md5/40b50d3ba65160eb842bc43241eca5e7 -LLD.v17.0.6+4.x86_64-unknown-freebsd-llvm_version+17.tar.gz/sha512/8cb54d63bcfa0ead6b8f8583e3e30ed676df4e8042b8a40f94aa443b1de211cab71ba4ab36ae804469876511641aeb5cd29e1843adda9e09e7b7e30a936c12cf -LLD.v17.0.6+4.x86_64-w64-mingw32-cxx03-llvm_version+17.asserts.tar.gz/md5/d999ad0a4c62fe11037ceed768cf8cb7 -LLD.v17.0.6+4.x86_64-w64-mingw32-cxx03-llvm_version+17.asserts.tar.gz/sha512/3c43e7eabe62f5a71d9b2411def56d5357a23ae50b639bb117eb795101f10ee896e886040db0f57c527873f07d68b49c8eb6f64a362419ba4d6ff9fbd2ecd9e3 -LLD.v17.0.6+4.x86_64-w64-mingw32-cxx03-llvm_version+17.tar.gz/md5/c2a7d97bc3b45591329284f55a821c26 -LLD.v17.0.6+4.x86_64-w64-mingw32-cxx03-llvm_version+17.tar.gz/sha512/d53f16798e8d19359ee6c86e9f55135838b2db78d2e69a2b0d01c92087b9bf1195d7cdcc9e2eb5c29debe02048af6b2d7dd83c0207600143c64b5dd8be647ecb -LLD.v17.0.6+4.x86_64-w64-mingw32-cxx11-llvm_version+17.asserts.tar.gz/md5/0a6eb0fb8f794e4ab1ffa0ca94e69968 -LLD.v17.0.6+4.x86_64-w64-mingw32-cxx11-llvm_version+17.asserts.tar.gz/sha512/9d1b5de37206ce411db00587a0d9dbb3d57c186ef84d2d60d20dc0c7718621bdf01dbf090ac1d2e63eec595e55fc39d9787d038766dbc0b4c49708e1b16bf09e -LLD.v17.0.6+4.x86_64-w64-mingw32-cxx11-llvm_version+17.tar.gz/md5/9b2f4c2988b177ac0928219406d5aa21 -LLD.v17.0.6+4.x86_64-w64-mingw32-cxx11-llvm_version+17.tar.gz/sha512/199bac9c28bb919eb1caef1eeeb5a935183a134be3def03f401794a2241b05d62468ee9ba12836d07bbcac508304c50c4c7f34d108fcb505a69a46a0eb89c6d3 +LLD.v18.1.7+2.aarch64-apple-darwin-llvm_version+18.asserts.tar.gz/md5/64c9a9f1758b9b292e0a3ef37f16ea41 +LLD.v18.1.7+2.aarch64-apple-darwin-llvm_version+18.asserts.tar.gz/sha512/cc740aaeb6ed29c56b2881e1488606338e4bd0e049ca4a5b8312b1d9129b778224570336698347e4562d632db9049e0e91ecce34ef68acb23a8bbf62455a81cc +LLD.v18.1.7+2.aarch64-apple-darwin-llvm_version+18.tar.gz/md5/1a8e11dba5cb574cde42de2b9703ff79 +LLD.v18.1.7+2.aarch64-apple-darwin-llvm_version+18.tar.gz/sha512/290300229576bb9155fe6bd24c0ee21beb41d0f2a46b208ab5a657b0199a7376c1f4cb07204c8ee1e6d202efe30ca040a6fff63c69b174120de3eb9866e344f4 +LLD.v18.1.7+2.aarch64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/cea134f347bae257cf5f55b6388cef81 +LLD.v18.1.7+2.aarch64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/16b59143e929791b0c3e56cfb4970d8b3c87adf6e847fa9e2aac17c4ff2aa311ba2c7511c1b0ae2f39d9aa92f87ad4d99c042fe35bec391ac865fedb72bd3b1e +LLD.v18.1.7+2.aarch64-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/5f903bab0e38fa608e8965acce6f020e +LLD.v18.1.7+2.aarch64-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/01e5f6a32958e04174c545f57c6c3b1bc88ccfd5ab18dcb9d67b92b55ebc7655a03bf963c4eaf7e5c3792d4691427a89db372e7534c6c8f965f8a715a32d9284 +LLD.v18.1.7+2.aarch64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/241a55374fd067f3736a2bb929e47015 +LLD.v18.1.7+2.aarch64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/f1fedea4e6b5f6f3bbf4d705034d6c51b06f011c2ecec1ae49c5b7bd123891eee8b991462d60be7fffd58f7c773afe910a06ec0b55b37eed9b4d09b9fdbd5068 +LLD.v18.1.7+2.aarch64-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/ff018c7448a7589935333e46739ee2c4 +LLD.v18.1.7+2.aarch64-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/b646c6a945b8f42b396164a8e87fc2e54b1ad05681f438dfba83fdd3712a60167aaffcb0300bc42d904eb4bd34c002a71642b59540ca01e64d6fecc6daaacdd8 +LLD.v18.1.7+2.aarch64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/md5/e6ee9423a82322b9233cafb1c92eed2d +LLD.v18.1.7+2.aarch64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/sha512/c915582a9ce2dfa8721741fb1ed19b719ba40f0092c2d29ebd68829ee558cef0b044a5e40985cff88e89129cbeed052d85fa5c6b6d87f9b3a68a6e89079ab4f3 +LLD.v18.1.7+2.aarch64-linux-musl-cxx03-llvm_version+18.tar.gz/md5/cc55112e2db358cf26d7bae3211d8e4f +LLD.v18.1.7+2.aarch64-linux-musl-cxx03-llvm_version+18.tar.gz/sha512/0ecb43045419020eea911f1767dae23a6b1e81bb155ec493e911a9412e45f7ec71461aea2e6fe346e641747139cae43d9435ccecaa7fd6a234e4d69bb06606ed +LLD.v18.1.7+2.aarch64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/md5/498b2909f80b20588135466d5211bc80 +LLD.v18.1.7+2.aarch64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/sha512/120fff24e85cf970670b20b5f4509475a3ae0d7621f8f67d018f3a7625548d736a3abc89f015966b1329c6b0a08a1db832e035ee3bae384e2c5864b73a856600 +LLD.v18.1.7+2.aarch64-linux-musl-cxx11-llvm_version+18.tar.gz/md5/1bcd298d5292f8e51f19b97fa4b27ab0 +LLD.v18.1.7+2.aarch64-linux-musl-cxx11-llvm_version+18.tar.gz/sha512/695c42557f9ee53b2e10bbf74653fbad4d02124b962a1f50cf719d2821607dfbb9c1bf638dbbc9e0e544f3020a9ef4a82decd13f886cc41ddf47c07a5e40eaa1 +LLD.v18.1.7+2.armv6l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/2323ff933feaf3754b442bee48a63607 +LLD.v18.1.7+2.armv6l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/47b8e490b89e04fb8886dae438e3ddcd53c4e98045de2b0def3988671827528c8e9ae296411464c0f17cc64bd3956644673f47a3817237f27e1c3ed16ac8ef01 +LLD.v18.1.7+2.armv6l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/md5/37cf8528666064a434296f2e0039e9c6 +LLD.v18.1.7+2.armv6l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/sha512/ea1504a859509f8a16030db7a65f42f0e78d67adf5946497f2178bf25456c0f2583af72c636881a4bdd1210dc0d377bdf300ef55aef5db8c56995424a1886059 +LLD.v18.1.7+2.armv6l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/1c341f2b161e2320d3d1a74685887f54 +LLD.v18.1.7+2.armv6l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/4f6fc099293deb1a2cf729ea7edd6e17fea0dc8b9fae9acfe34e00b1f5c798933df9538c805c8d28c6279eb38f9ebae2a1aeb1a2f23087352c6eeb3b27b63ddc +LLD.v18.1.7+2.armv6l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/md5/e306d59c71b0958c77108e650fac2612 +LLD.v18.1.7+2.armv6l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/sha512/79fd7cec0e169a9555ec9b0acc3248991e2e37a1d5bb422808ffcfd4f47e79321560b7985c82dfe070fb0b5ded5c160d83e358399c6e7608eeb62cd4a1406f88 +LLD.v18.1.7+2.armv6l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/c1d080f1aebb58778d730578fb113290 +LLD.v18.1.7+2.armv6l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/1f420da1897bd0a61413321aaaf032e8ed38d59e6dfe3313ca3a6ee6582ae6c566e3761ca8fcd1f5a964337ba8a9b3e73dc55ad68aca139beeb45e43d51e862b +LLD.v18.1.7+2.armv6l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/md5/6f4e0c7d2fe9ac254650dcd2842dafa8 +LLD.v18.1.7+2.armv6l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/sha512/bbc71b334250e5e6429766d88595adbb671a206630987ec2a27e05711ff0f844487dffc1c136052ec11394e9d5c51c70d1b75d5348f97d3bf7fab463291e9dc8 +LLD.v18.1.7+2.armv6l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/76925b9a7bc249b2227390c479c54f8d +LLD.v18.1.7+2.armv6l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/20643ecb79732e3ae9666116dbd0763c18b808afa78e6a14998aadc7265cccd6efd28670592db61d3d27b8d3023be4c5f3df41fff9e1b38d61abf76829090b4f +LLD.v18.1.7+2.armv6l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/md5/399b9aac140d9050088fdb187ed4645f +LLD.v18.1.7+2.armv6l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/sha512/8bab65965670fe392e78d0b9dc78c92cdcf202898f6d5a3174eb89ca5cb95b995675c8a7d81bbc4e95e490ad1a43d9d29d7907b7006789c0143a1d8f24cccaeb +LLD.v18.1.7+2.armv7l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/026a4f5ae9eb3ac05e5e8fa894d77a5b +LLD.v18.1.7+2.armv7l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/4bca8bd558619260cddf4e2f4593cbb2a0691b5ccc6d1dea6dfcc5a2b5f51d7d1a76c35e481244e211e2eacf32bd628df5ad0e6c75e5185bb1d9b569f6acbfd3 +LLD.v18.1.7+2.armv7l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/md5/f898ceabcba052b7e6713a2b2c208a92 +LLD.v18.1.7+2.armv7l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/sha512/92be1910f795390be5f15ba5b2c220a3209a5f7ac04fca3f5229486628bcf5d2f20cf6e4dda8b41d6beaaff42a68a9ddb95fdacc6eae33b9183b581e9a194895 +LLD.v18.1.7+2.armv7l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/e366058cf69a4367945bdba9523f2a0b +LLD.v18.1.7+2.armv7l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/45a786e8d0162bd5bd01c029691d2928d3744ef4a7a1efc2e39755dee2f9a9ae23ee725f0454ca601cb9c082a342209e9129df851314b5757c74767b13508fc4 +LLD.v18.1.7+2.armv7l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/md5/665a8502170729c86ea95a7ea2fcce0f +LLD.v18.1.7+2.armv7l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/sha512/c1a2a85c9ce14af8c91bc9a599393c52c0b8a585057366b1ceeed34c5db44641ecd0c9b377bee80cb4951fc7102fbb4f21fd050126bfa5bb4e582ffefee17035 +LLD.v18.1.7+2.armv7l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/b90b2130262f63f5189cc8e4a65e4433 +LLD.v18.1.7+2.armv7l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/c1cbfd38c82d676c3fdbec486691334cf7bf4115d9ef2665012b71725c28545a49f34edf5689ea0352822c811c24c89cc152d1fccd1586b17ae8e6b2503641df +LLD.v18.1.7+2.armv7l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/md5/2d5360da4b2c9ffcea5d0a646a7c114b +LLD.v18.1.7+2.armv7l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/sha512/73323e0937fe4423883480294c8df44744acde4f47380e35535cbe69c855c0e35e86a1eced3085ae0285f284f47af5ef237f4650bf2b6a8b9d5308efce88fa02 +LLD.v18.1.7+2.armv7l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/a9b9a65938a7701aaac6fa706481c867 +LLD.v18.1.7+2.armv7l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/fe8243aa131ad8be54f0fca5754c2e68ec39049004ec8feed499731c5228a7a46e303ba866b9f9a55e5318c73d8a46d964673e111f6c60e5ae1628c568d7d894 +LLD.v18.1.7+2.armv7l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/md5/0d9592a287c9231ae2db65000be2cea2 +LLD.v18.1.7+2.armv7l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/sha512/4ee192dd33f518d2735a829ac8f822b5672b39e8c2254987aea6e5f2f0056213bd85d84c4050d52ba9ac8c35762521c324fe2d6e18db0396e7142af9cb61a561 +LLD.v18.1.7+2.i686-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/d487598dec9969485dcf785fc0968bd4 +LLD.v18.1.7+2.i686-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/8d3117739919696b9b0c9ae398f1b1e9db8bd3e2e27839f62b3551c22ae2517f8abb69e57e23d125002bb466889b7352e69c1e9dfd9abf1c5433f274e928b341 +LLD.v18.1.7+2.i686-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/943434b08dffb54e8cf04ae7bee34923 +LLD.v18.1.7+2.i686-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/77b7bbc5d988cf36ecd10609e091cf24dea134cd32c7ee96dec7bfe1a4942553b6205653edc16c8454261f621966daeb267f42562172bab4cec9693ad733d867 +LLD.v18.1.7+2.i686-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/cb9e371947ad415de048636ed78ca48f +LLD.v18.1.7+2.i686-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/c00b696fa146e8c29b37f15f78ab3325db9b3f5b3514e615f145b4eb7c9c8788662cfb6255b7dead596cad8c576b378f7459c2c85d462b597ba5e21adbac0536 +LLD.v18.1.7+2.i686-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/485f061ee8425f042e4dd3042388bf8a +LLD.v18.1.7+2.i686-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/845a47a36c61b305bb70b1249f6fb7c4e8f740acff90d3e850ab2e887f7d959ae263431a02305bf7587e4194463f9932769d500a19709bc479eb6e6168325421 +LLD.v18.1.7+2.i686-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/md5/f234526410e779188f3d22da438a4926 +LLD.v18.1.7+2.i686-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/sha512/12e2c9fc5385ff142bf82956268230fb01a6f1a1fdb3a6c1e13afd341dd2eea970b707168d5f45960dc9ebbf6d6598af0ceba371172f624ae823ea1eef4e9031 +LLD.v18.1.7+2.i686-w64-mingw32-cxx03-llvm_version+18.tar.gz/md5/e68cab4aec1abcfce12a13e3d1f67dac +LLD.v18.1.7+2.i686-w64-mingw32-cxx03-llvm_version+18.tar.gz/sha512/67755b34ebe04f4d28be3be2a37df46b5e900f38dc4908875f66671fbb740cf033f2fd9af5116635f55025f330f7b1a478cd4900db9d00e4699b591a16269100 +LLD.v18.1.7+2.i686-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/md5/4a71aef80b75b2ea1a5b7f8521afcf5f +LLD.v18.1.7+2.i686-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/sha512/9deb3e9615ae15dba8c744b22416243304d30f100c8d17538fcedbc18787147505f74ecc2f933fc54101527847503142cfe84a46a95ca3c57987996e3b8583f1 +LLD.v18.1.7+2.i686-w64-mingw32-cxx11-llvm_version+18.tar.gz/md5/9b28ee75d05cbaabff57fd45cc0d1cf7 +LLD.v18.1.7+2.i686-w64-mingw32-cxx11-llvm_version+18.tar.gz/sha512/bfd3d6cfd4a5a2fbfe940f64d47a86a598360e90619f8175a2d1306f0894610f13fc44ba099ad59d2989beabf491df08a5611bcef3fd61b6391ea0230b11a432 +LLD.v18.1.7+2.powerpc64le-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/7962fc6f08531f0dcfa44bd667f31582 +LLD.v18.1.7+2.powerpc64le-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/2c936064685f12ed6764c187192023118e97dcbff6ca1656f0304a40772b4ecf55ee0296b3c2a00760f5bb437162e2b737635fdd59b889d35756d697fc7e6b72 +LLD.v18.1.7+2.powerpc64le-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/3eb4d78af670d446f696449a5e71e3ba +LLD.v18.1.7+2.powerpc64le-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/315dc76799f3e443fdb5ebbecf96a08070f8251930a26995de892b8e67bd35bbb365f2cc5fd93bc7cbcbc9edd08280ee8d2a36b28a704866dd3fdddae4969455 +LLD.v18.1.7+2.powerpc64le-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/e73cadd0354897bd5bb611cc1c027858 +LLD.v18.1.7+2.powerpc64le-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/6f444a4ea22e7108ab75686ce9cd78c0db0a677e39e8434896fb1ec90b9dc013abf7de1024d329a9726dabf229a8a68c27a11f211092e676715d282efb7b8504 +LLD.v18.1.7+2.powerpc64le-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/aeb310f106f31126dbe53459e36d33bd +LLD.v18.1.7+2.powerpc64le-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/cd18c115415dd92bc7fbb5c29cacc5848b1f3851c3a526ff9c0813ad46824df0a4f13a66b1e6641ed11b44b5b937390619f01666fe6d5a047f1772f0ad03c941 +LLD.v18.1.7+2.x86_64-apple-darwin-llvm_version+18.asserts.tar.gz/md5/300dc28f7af6aaa69cec9a214a57fdb8 +LLD.v18.1.7+2.x86_64-apple-darwin-llvm_version+18.asserts.tar.gz/sha512/dcb40c5934118c204968cb963a3fae91179eb1e31f5397975ca98c8a7aaecaf2a7f81847bc426fd306bb76970794502ed4f94d8f461b96ea90362130f44520e7 +LLD.v18.1.7+2.x86_64-apple-darwin-llvm_version+18.tar.gz/md5/e1f23fef82fbfcbc28899677f12658b3 +LLD.v18.1.7+2.x86_64-apple-darwin-llvm_version+18.tar.gz/sha512/b6b585060832d53827376ac6c00cc8bd5dfbf091c38c87020f6de42adc86dbe4fc33ec2c17f4433176c79a509681d694ed1502b179efcee2c4dd4c10a26e87a2 +LLD.v18.1.7+2.x86_64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/5dc96eef71dc28611bc998ef966371c6 +LLD.v18.1.7+2.x86_64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/781993c75bb07db96d02b5a7e779116864730a9bb941b64420a435956a7ecd501b5b2673f1854c09ece5f0c73559d5723c271d6352be57ddae6801a695629362 +LLD.v18.1.7+2.x86_64-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/8a1fe0ccf7699ab7a7a514b620112a70 +LLD.v18.1.7+2.x86_64-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/d002083045d3eb7c749f2e97527c1228cd317a8138ff254228e43594a6cabee47fa363785466ebc2874cc438457640ff08a836eec7334afac451506ea7bbed03 +LLD.v18.1.7+2.x86_64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/331be92bd3d76bb8e86991b7832ad41a +LLD.v18.1.7+2.x86_64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/7b1c6df53311a17a92a41cb67ec476f947949c4ca5d15a643badaf9f01e76a186abbb6e156f95ad1605d83250df4e081164986a6b7fcb3238076b0ec5a3bb565 +LLD.v18.1.7+2.x86_64-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/97c7f5267ad6927f699a25ce44f55a70 +LLD.v18.1.7+2.x86_64-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/7b847c6026fd7daeb17a4459b852562ce6664b2f406664be672bcc384dd5a79b9505561fc61dd8fb78a903a2ed4978f322cccad19f5a3966bac856e877c11ef7 +LLD.v18.1.7+2.x86_64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/md5/c86da6a396fcdddbd26cfd71c0f70458 +LLD.v18.1.7+2.x86_64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/sha512/8d5b75b43167080b8ea456e516c9ace02ee6066ce715a56f0b42cb8045b965b1cf8d4ebc0786c23be4544693ff858816a6257b0638ec11e077df32ead62f7efb +LLD.v18.1.7+2.x86_64-linux-musl-cxx03-llvm_version+18.tar.gz/md5/d72e175272ed893688d18e868120c575 +LLD.v18.1.7+2.x86_64-linux-musl-cxx03-llvm_version+18.tar.gz/sha512/9a46eeca8c7a8be65ed487a74227534e08a257e404814c44730f12a5bebc8cd160998cfd5ed30189aa606ddbe602e1b1788e465e4a210103c6726a7fd230abc3 +LLD.v18.1.7+2.x86_64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/md5/0206fdaa9582ae3bddaed1b6fd7a8cb5 +LLD.v18.1.7+2.x86_64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/sha512/584a67f603f656ca5d27aa0ef2e425ad385612aff06cdc1d534b5944939a09246c93954fc153b8a89acff721e657a8903af9a640abc252d4e452f348781bca98 +LLD.v18.1.7+2.x86_64-linux-musl-cxx11-llvm_version+18.tar.gz/md5/0dd14af342467eac2e13cad4acbc881f +LLD.v18.1.7+2.x86_64-linux-musl-cxx11-llvm_version+18.tar.gz/sha512/918f2c66898f828414009fa6ee273da5bd654e4b787ebb4d703f0be27e388b46870d68bd58c4f45638d276c61c1bfe2f3c67fbf34dfb5578158d072f82d927de +LLD.v18.1.7+2.x86_64-unknown-freebsd-llvm_version+18.asserts.tar.gz/md5/b373e1bf2a24f34496754438e563a5e9 +LLD.v18.1.7+2.x86_64-unknown-freebsd-llvm_version+18.asserts.tar.gz/sha512/a739f29e332be74cbcc544903d08bbcc12c3e9f5c3d02d130ef1c69426ead2c74b14f98ac79e88ba29fb2e2dc3b28b7d81c9d42f2e27e0ce9442f6a0e81bb8f0 +LLD.v18.1.7+2.x86_64-unknown-freebsd-llvm_version+18.tar.gz/md5/1fdbf6aa0751788611054f7e98024104 +LLD.v18.1.7+2.x86_64-unknown-freebsd-llvm_version+18.tar.gz/sha512/2015b8e84642b2434d1089908354b47b080d5683f1c7eb2c09de09abb3674e7119ce4ecfa858bf8129fd9e9075bb45f2e53a997421f2457aa9b5c4a9d7edfec8 +LLD.v18.1.7+2.x86_64-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/md5/85bd5a9e312e83a09fa5b7fd6abfba76 +LLD.v18.1.7+2.x86_64-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/sha512/0a5cba5c65abc72361a780f64e64c463797aefe52994699d8d785437b773530e49a5fc2746e36bc5a31aabf4eb4343870aa448f8fa2b119ede3e1c4ea228cc9d +LLD.v18.1.7+2.x86_64-w64-mingw32-cxx03-llvm_version+18.tar.gz/md5/ab07ed76a796d86cb6ac2ae4fc563eab +LLD.v18.1.7+2.x86_64-w64-mingw32-cxx03-llvm_version+18.tar.gz/sha512/485117c7e1daca401c1cfe77324e8f5961f6f33ed2a3c907f4c4a2bf9c45c14d929959cf8e4d9cca9ad112a3ce6a851e336cd793bd5ee284c87b9fe487700ecb +LLD.v18.1.7+2.x86_64-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/md5/852449a26af61d8554fb1b4c22c4384a +LLD.v18.1.7+2.x86_64-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/sha512/a080d2da5ff4b832822e099f150f0c15b985d54678a9508711f7f435d6ceec68eba12b5f8c25db0b4841dc5c5edb003b74b4fef391292b9407d7bda73d35c4f5 +LLD.v18.1.7+2.x86_64-w64-mingw32-cxx11-llvm_version+18.tar.gz/md5/eb999bcb67f789b6443dbfe907bc61e4 +LLD.v18.1.7+2.x86_64-w64-mingw32-cxx11-llvm_version+18.tar.gz/sha512/811f72ce250184ccdfa30aa992884f1bdd0a791fa125f089037bf1af45b844d76807c5662a904ec9312b79efc565fd0957f195a70a39248eed99ff53f3284cba diff --git a/deps/checksums/llvm b/deps/checksums/llvm index 22d86ec2e009d..122aeb9a53337 100644 --- a/deps/checksums/llvm +++ b/deps/checksums/llvm @@ -1,111 +1,111 @@ -LLVM.v17.0.6+4.aarch64-apple-darwin-llvm_version+17.asserts.tar.gz/md5/db3b242aac30d823cd911ae3424b3d7e -LLVM.v17.0.6+4.aarch64-apple-darwin-llvm_version+17.asserts.tar.gz/sha512/5efe8bad36e748ca1883b23f5eb6da416ebea77f42232e2de9268d9aa92af868b2a20b3c9062f77e734a58ae607b4dfb134e2f8c7879652cc643802379296196 -LLVM.v17.0.6+4.aarch64-apple-darwin-llvm_version+17.tar.gz/md5/640e9260e4b4235b9497720bced5330e -LLVM.v17.0.6+4.aarch64-apple-darwin-llvm_version+17.tar.gz/sha512/b7d193821ce8de809ec4c3d035ea1cc9b889e2c22ba0d263d25b8c01474a6a353abc9c9b8bf8feef686f00cd6055f06f20cb3f5b85299cc9764fe75c7b3fb21c -LLVM.v17.0.6+4.aarch64-linux-gnu-cxx03-llvm_version+17.asserts.tar.gz/md5/898954f176232716590f3c885af8c824 -LLVM.v17.0.6+4.aarch64-linux-gnu-cxx03-llvm_version+17.asserts.tar.gz/sha512/8251dcc31ca7d2c827ad73668d9e422f777a219d444e9e00c0a0e16b895ffaceb266701938f630d4f354e3ded736061be69d3398f3810dc0df5b803a508bebc1 -LLVM.v17.0.6+4.aarch64-linux-gnu-cxx03-llvm_version+17.tar.gz/md5/860b7b3b26e3fa5ff2d1c77d087cbbc0 -LLVM.v17.0.6+4.aarch64-linux-gnu-cxx03-llvm_version+17.tar.gz/sha512/4c4dcb47f952b87ea506e6c1cb07e1b978dee4aef14381e78ea389de728d49b351c401b079790a1d1f8145853840d019d02a906a39f3c1edb705c8cf663728f8 -LLVM.v17.0.6+4.aarch64-linux-gnu-cxx11-llvm_version+17.asserts.tar.gz/md5/9cece7e656a511fc8f47fdca094a2695 -LLVM.v17.0.6+4.aarch64-linux-gnu-cxx11-llvm_version+17.asserts.tar.gz/sha512/9f918e9a4b552911b58ff43e829acc8355904fd7f050a25ba9e08437b8f7585d48bcd842c79bef756d2afe83fd0a690331b5cb51fd55a2bc4bab7e3c615987e7 -LLVM.v17.0.6+4.aarch64-linux-gnu-cxx11-llvm_version+17.tar.gz/md5/66fe8bb24feb2779828432e0d996381f -LLVM.v17.0.6+4.aarch64-linux-gnu-cxx11-llvm_version+17.tar.gz/sha512/090adde3f779fd56815992971a532dda793d3ce4462497daff66c065822834821eb6a0b9575f94241a760cffe4cfdce8b7e8a2b1acdefcbb62fa9db55748ef71 -LLVM.v17.0.6+4.aarch64-linux-musl-cxx03-llvm_version+17.asserts.tar.gz/md5/b3a1eab6dff60e4c9dc770ef1d6d108f -LLVM.v17.0.6+4.aarch64-linux-musl-cxx03-llvm_version+17.asserts.tar.gz/sha512/eacc5a3fc376359e27ff795f63aaca0d1cb3c57ca0dcb27e9a43887dbcb6a2923b1e9895ef0c0fdd3545b7edb5cac8598515f464c27f5eda25dc65425f5e0c50 -LLVM.v17.0.6+4.aarch64-linux-musl-cxx03-llvm_version+17.tar.gz/md5/047ea0fe65332c30dda16799e7999185 -LLVM.v17.0.6+4.aarch64-linux-musl-cxx03-llvm_version+17.tar.gz/sha512/c62949b9e4ec97f372d3d9fe7bceae923d54db5afbc0902d74b7ebac66dcc1de7d7ba12b10b5028aa1489166cf06b30fc2610ad84bee9cac95b08bc7b7af7f05 -LLVM.v17.0.6+4.aarch64-linux-musl-cxx11-llvm_version+17.asserts.tar.gz/md5/0fe165f62c2fee6dc0fd3167c6da9ecb -LLVM.v17.0.6+4.aarch64-linux-musl-cxx11-llvm_version+17.asserts.tar.gz/sha512/9bbdf63b00ca88afea787069da2c64ea6a9478c2f929bb540fec5d2664c19249ea63a5b69d2e703605ff5bde28a029e5bcde1470e859abdb1f0cc8da960065d3 -LLVM.v17.0.6+4.aarch64-linux-musl-cxx11-llvm_version+17.tar.gz/md5/0f07d3c14e1bdc435a9c69431b354c51 -LLVM.v17.0.6+4.aarch64-linux-musl-cxx11-llvm_version+17.tar.gz/sha512/f3f572dd805bfb14713a6f4ce79e91c3c9b2fd7008ce9f4ab1e2a55f0e88b192f48beb6ad3954b531261ecdcfbe8d26cbf931057e43e472ea244beae87cfbfbf -LLVM.v17.0.6+4.armv6l-linux-gnueabihf-cxx03-llvm_version+17.asserts.tar.gz/md5/e7b10dd01bcf10e9c3100c4edb5b127a -LLVM.v17.0.6+4.armv6l-linux-gnueabihf-cxx03-llvm_version+17.asserts.tar.gz/sha512/a86a213de97ad709fa2b0afd7a2103f58c5292bd9e1f939dd79fe02574065642b67823a0b05f9cdb054c5b6546b3051873c67c93bad57c0f53b8327285ef97f7 -LLVM.v17.0.6+4.armv6l-linux-gnueabihf-cxx03-llvm_version+17.tar.gz/md5/480cfee009635bfb78c164fa10745e36 -LLVM.v17.0.6+4.armv6l-linux-gnueabihf-cxx03-llvm_version+17.tar.gz/sha512/414af42a442224f780eb6e6455483a6a210250d28040138998ef01c57c63176aa77626ba8b9985ad9ca9a397fac5c1a8abbe0e173a585d218de8b036cec96f67 -LLVM.v17.0.6+4.armv6l-linux-gnueabihf-cxx11-llvm_version+17.asserts.tar.gz/md5/1b6e3e6fcf6b20e824aea1b3b510f989 -LLVM.v17.0.6+4.armv6l-linux-gnueabihf-cxx11-llvm_version+17.asserts.tar.gz/sha512/7370730b97875e1f6b8b3576d68d0d4a3112ff7be66c8f04901f905938cdb495b67f4676f03c1e6f0e4f9612e2849d7a9f02a932bb66354d007c2e4cfb8fad99 -LLVM.v17.0.6+4.armv6l-linux-gnueabihf-cxx11-llvm_version+17.tar.gz/md5/24bad94fd9ce261880ff589829dbeabc -LLVM.v17.0.6+4.armv6l-linux-gnueabihf-cxx11-llvm_version+17.tar.gz/sha512/cd52c2c036cdc7d986731b76324c0d241fea9d9deb3a94963b5efa01a1649042c0ec062e2cfc6c27bc747637ace09106238d07aab0df84c448755a61571e6a68 -LLVM.v17.0.6+4.armv6l-linux-musleabihf-cxx03-llvm_version+17.asserts.tar.gz/md5/78273dd81559e0812eb497c91bec8279 -LLVM.v17.0.6+4.armv6l-linux-musleabihf-cxx03-llvm_version+17.asserts.tar.gz/sha512/1b28a9f2300d4777406d125eee8fd8217dab7ee67db38334cb0f51a749f27baa370d6229c4396f12a63dae210c0d772b83d79feeeb6dc17f19184832eb15859f -LLVM.v17.0.6+4.armv6l-linux-musleabihf-cxx03-llvm_version+17.tar.gz/md5/3a88701757a155ba35cf911b1ad6528b -LLVM.v17.0.6+4.armv6l-linux-musleabihf-cxx03-llvm_version+17.tar.gz/sha512/aca7a33d28e1ddeac19d9c99fd2ab81268a23d2523df7d300c8d1999481902f7aced3e4615d40bc7257d38d10867a8440d9811db81300db1784b2515c3bc8fa5 -LLVM.v17.0.6+4.armv6l-linux-musleabihf-cxx11-llvm_version+17.asserts.tar.gz/md5/3be9234f6718d0684a40fe089af08503 -LLVM.v17.0.6+4.armv6l-linux-musleabihf-cxx11-llvm_version+17.asserts.tar.gz/sha512/9acd3d69ea99f4e660978d830ead8253f8623d6fb66aad0c79db211f975f42b58254b7f47e284e751c94609934c6895b4a2e662fa0e8ac8835cce1b60e653ff4 -LLVM.v17.0.6+4.armv6l-linux-musleabihf-cxx11-llvm_version+17.tar.gz/md5/583608958fe5159e105f349f73bf9a40 -LLVM.v17.0.6+4.armv6l-linux-musleabihf-cxx11-llvm_version+17.tar.gz/sha512/cc574e3e9f457194b4ca01e63a6a55d46f72780833b496f570dc5b7c1d85d751f02093da95061162a8d66b0118a1cde677751b32e53261ac0272d540925fcf0e -LLVM.v17.0.6+4.armv7l-linux-gnueabihf-cxx03-llvm_version+17.asserts.tar.gz/md5/3318c8aced1cd7dfae6cc5722c7ff590 -LLVM.v17.0.6+4.armv7l-linux-gnueabihf-cxx03-llvm_version+17.asserts.tar.gz/sha512/a202552fcd12c6379cda41a235be1eab46b7ee2c28b4cd9c9ebc581a5ad2eed3f0c54d7ed861c9045272ec04d598707877b6b831c5109b12b4d2de80ac53bd2f -LLVM.v17.0.6+4.armv7l-linux-gnueabihf-cxx03-llvm_version+17.tar.gz/md5/a5718bc977c437d3268a8e4681d2adce -LLVM.v17.0.6+4.armv7l-linux-gnueabihf-cxx03-llvm_version+17.tar.gz/sha512/45d053db2325ff637edcebb60167e948f42b7a6e8e6dbb14b2b0785459e06667ee42c1e01b13ed9ef09b51fefb0bbdd861ad59a3320f76986fec60129f937cbe -LLVM.v17.0.6+4.armv7l-linux-gnueabihf-cxx11-llvm_version+17.asserts.tar.gz/md5/53f2205312d55810fdbc1fec961d3560 -LLVM.v17.0.6+4.armv7l-linux-gnueabihf-cxx11-llvm_version+17.asserts.tar.gz/sha512/bb80a8003bdaef7da016138f99e8c53223642a9490c01b55ded0d02f6dd69c8460df11bfde7cbbc5ba1b3c331e2d2e6a8c6f7ca83aba20112bc0f56ee907802c -LLVM.v17.0.6+4.armv7l-linux-gnueabihf-cxx11-llvm_version+17.tar.gz/md5/737492de94fb15e377789aafd66e817b -LLVM.v17.0.6+4.armv7l-linux-gnueabihf-cxx11-llvm_version+17.tar.gz/sha512/2d31da6d69deb859513ae6db6e3fc5c2bf3703648301b1c520154b6f3aa0eca12c8290026643384e40b261755d8c3061c02d685dc53f5c14104498657f52d167 -LLVM.v17.0.6+4.armv7l-linux-musleabihf-cxx03-llvm_version+17.asserts.tar.gz/md5/99a0eac6aabafb1edf3bff32c283dcbc -LLVM.v17.0.6+4.armv7l-linux-musleabihf-cxx03-llvm_version+17.asserts.tar.gz/sha512/f65a01d75c3330299584f8eec1d25f54d89162e5359a7dfe0f73de76aaa371751d3e5008a0dedf5de55ac0f29613f0f2ee1d9dbb7f69871dd0e85e047b44b28e -LLVM.v17.0.6+4.armv7l-linux-musleabihf-cxx03-llvm_version+17.tar.gz/md5/b8947735e7e7f9687c9fd97c72681e9e -LLVM.v17.0.6+4.armv7l-linux-musleabihf-cxx03-llvm_version+17.tar.gz/sha512/a6c699b0994a132867071f6cabffdd6bfdb51eb4fe7e5762e836d420aa7d61a5165d899037df2470e9cdb04bd64c4c153ff83c49e30f42a120fd5b5090ea4fe6 -LLVM.v17.0.6+4.armv7l-linux-musleabihf-cxx11-llvm_version+17.asserts.tar.gz/md5/fc3143ac4c492cc2041d73556a84897b -LLVM.v17.0.6+4.armv7l-linux-musleabihf-cxx11-llvm_version+17.asserts.tar.gz/sha512/3e7f3281b0fee548a4135893be999456c39aaba04644f4bb55247d514257b3700d36fed376fb1ff7b3ef5546a43f791b202a2c1ddf6f924a63730c56254eeb8c -LLVM.v17.0.6+4.armv7l-linux-musleabihf-cxx11-llvm_version+17.tar.gz/md5/38f9a63bd7b6275e4cec5fb05d2ac163 -LLVM.v17.0.6+4.armv7l-linux-musleabihf-cxx11-llvm_version+17.tar.gz/sha512/b7a131e2d1838cc3dfeca08fa8f6b329ca714e909d35bc6429952e690743a321b8f2e242f358adfe719302742015306e3cdc1ac0ce5be613a36447e53292f9d3 -LLVM.v17.0.6+4.i686-linux-gnu-cxx03-llvm_version+17.asserts.tar.gz/md5/ef301dbee02ae00dfb6f3cdd9e67c714 -LLVM.v17.0.6+4.i686-linux-gnu-cxx03-llvm_version+17.asserts.tar.gz/sha512/944849a1261b3ac3a5141fad55397a0de423a73f57ec6b8d725ef09b3233fa6bd6e76be4c8c4e77c80e3b60bb3ab135d8adb30760fec1d21eb699aa1868f9a09 -LLVM.v17.0.6+4.i686-linux-gnu-cxx03-llvm_version+17.tar.gz/md5/1777a48a9188895ed07163df4594a688 -LLVM.v17.0.6+4.i686-linux-gnu-cxx03-llvm_version+17.tar.gz/sha512/e5226a9b3f87c63b32e69e43f96ca07c32b34742955c5e608be7843dc1c003b75e065ed5ab29c2a4144607df23d97852382d7fe7e25f98abaca2493200ee8cdb -LLVM.v17.0.6+4.i686-linux-gnu-cxx11-llvm_version+17.asserts.tar.gz/md5/e8b3d76ed47923cef55a71033f78ceeb -LLVM.v17.0.6+4.i686-linux-gnu-cxx11-llvm_version+17.asserts.tar.gz/sha512/88825e210479ba2504892af2dd01a3f0a1488f05ec5df6b352fbe0d6d8bcc691fab0e3d3b31aad2b14eef860dd8ef5bf56e83647583e7c3fde847ec7a0a651cc -LLVM.v17.0.6+4.i686-linux-gnu-cxx11-llvm_version+17.tar.gz/md5/ad634b98e24aa296087aaf11e6d70828 -LLVM.v17.0.6+4.i686-linux-gnu-cxx11-llvm_version+17.tar.gz/sha512/97bb219361efc3aa847fe53fc20669821466aff399ac47bb312af7d0899bc6af0533a0e4b490d74a0fbb3f5e3d0b91af23023109fc9a0138ef56630055e5792d -LLVM.v17.0.6+4.i686-w64-mingw32-cxx03-llvm_version+17.asserts.tar.gz/md5/cbb4bed17e57832bd99affd1a01c5e9b -LLVM.v17.0.6+4.i686-w64-mingw32-cxx03-llvm_version+17.asserts.tar.gz/sha512/948dcfcb18eb1288f4d66f9d9a7c7b234956cb8bf87d6b52b7d639dac60360e4a3b9c808a908b2d298adebaa9b6e63d8df78c57a1b0ade613fe0da0921d07807 -LLVM.v17.0.6+4.i686-w64-mingw32-cxx03-llvm_version+17.tar.gz/md5/c800bc4f0f0ddc5d2626512a949d9b79 -LLVM.v17.0.6+4.i686-w64-mingw32-cxx03-llvm_version+17.tar.gz/sha512/4e0c9091d580d8d8bce9d5ee63beccef52dbe4428d29fe5315891ce63a0115f4226029bdd68612d813829ef49f0c6db9b5681c83cd5bc70ded55541466296cca -LLVM.v17.0.6+4.i686-w64-mingw32-cxx11-llvm_version+17.asserts.tar.gz/md5/4439c5a18ff9c3bda01aa989b5d7a1ec -LLVM.v17.0.6+4.i686-w64-mingw32-cxx11-llvm_version+17.asserts.tar.gz/sha512/5d17b2da2d2a218ecd866d9164527bf4762090effc908fb5b93b8f4125518e2925ca65b5e96210b3e2f77750f2a3e3c2edde8ccde3ab779561191ce7eab294d4 -LLVM.v17.0.6+4.i686-w64-mingw32-cxx11-llvm_version+17.tar.gz/md5/9544f9d46eefbf593ad8b665a1cd73c6 -LLVM.v17.0.6+4.i686-w64-mingw32-cxx11-llvm_version+17.tar.gz/sha512/8baf49c6495221ac0d0a039bf7988fd4890cb750519b0e2e4b44e8dd504c417ff9635d66d43ecef75e3d0d397b1e47aad010fb91782286b1c26f7785667d58c8 -LLVM.v17.0.6+4.powerpc64le-linux-gnu-cxx03-llvm_version+17.asserts.tar.gz/md5/8f46834c72ac617d41befe0abfec29a0 -LLVM.v17.0.6+4.powerpc64le-linux-gnu-cxx03-llvm_version+17.asserts.tar.gz/sha512/c131d322d45a95c74ad01bd35c094b5e30a47535c6cf5cd7c2751b99f8942c1cf0c27c6039b33050a4e140ef856d79c5878a81fb98db0751d43b6e463070dcc6 -LLVM.v17.0.6+4.powerpc64le-linux-gnu-cxx03-llvm_version+17.tar.gz/md5/14f97547b230bb2774bd1bcbc9e44fcc -LLVM.v17.0.6+4.powerpc64le-linux-gnu-cxx03-llvm_version+17.tar.gz/sha512/ff1d8ed1a479409b3bc611cef9d6429bb7f1118972340ecf7c5b8cf6db28a6cc79778e800523c655c334496d3460a93d6c0f42a1488dea58d8c2416afd0725d2 -LLVM.v17.0.6+4.powerpc64le-linux-gnu-cxx11-llvm_version+17.asserts.tar.gz/md5/6cf4a661be00b3d007c67f7af80b9cc2 -LLVM.v17.0.6+4.powerpc64le-linux-gnu-cxx11-llvm_version+17.asserts.tar.gz/sha512/497e853d4b06c64a61de09a1216ac612ee0ae4a3bc8f01ee9b919a82c82706bc045f0a641c5a69547b68a36597c2be8f699f711f60d5af5fbf290421a4e76816 -LLVM.v17.0.6+4.powerpc64le-linux-gnu-cxx11-llvm_version+17.tar.gz/md5/4e8db53272b73e5bf7c21413cebea308 -LLVM.v17.0.6+4.powerpc64le-linux-gnu-cxx11-llvm_version+17.tar.gz/sha512/184c1cf3e36efdd9da14f6e3decd015268f1a0a9157b9c677877f600bcb4c9d20a7f37d6fb830b22012bb7cf05d7af86ff97dce046900c1a9a90c49b0a6c3bda -LLVM.v17.0.6+4.x86_64-apple-darwin-llvm_version+17.asserts.tar.gz/md5/c06ecd1d4ab8e4fd73c6cba18bee9750 -LLVM.v17.0.6+4.x86_64-apple-darwin-llvm_version+17.asserts.tar.gz/sha512/eee12b4e551d21ad35f780ea8f3ace4b43efede66297e6941da78ffc768fb28c31a1f7e1ec5e11495d95d456ff2a929400984282d2f2230c55ebeea8005c352c -LLVM.v17.0.6+4.x86_64-apple-darwin-llvm_version+17.tar.gz/md5/72975355fb31f13f86be0afa188dc436 -LLVM.v17.0.6+4.x86_64-apple-darwin-llvm_version+17.tar.gz/sha512/9a82c8148db2c67c50255c70fbaa3c6cb60fb6bea700357a39ff5e59dc1fb615a13c647331b494244b88001b525d4cd61035705b2ce0e6590b8894797efcfbe1 -LLVM.v17.0.6+4.x86_64-linux-gnu-cxx03-llvm_version+17.asserts.tar.gz/md5/04820df9e180b7008598eeebe49bb981 -LLVM.v17.0.6+4.x86_64-linux-gnu-cxx03-llvm_version+17.asserts.tar.gz/sha512/ad5fd5d96f22d67e3ada73b8f0deecff2df212a8e8762d4acdede62564f379496351659232fc5450d23b4e3b8a55af95f48725841233a6a2448d18d3fdc1adfb -LLVM.v17.0.6+4.x86_64-linux-gnu-cxx03-llvm_version+17.tar.gz/md5/59af89fcc77a0eecd7c9e8cf812f035a -LLVM.v17.0.6+4.x86_64-linux-gnu-cxx03-llvm_version+17.tar.gz/sha512/a5c486b44cbfb41ef0623c067e42cfbc5216cf2c09f537b8b792aba814612ded170e6a99a11bdaf9f3790d4af06f7f058b6e7a66b2f8513a8522044a83007a11 -LLVM.v17.0.6+4.x86_64-linux-gnu-cxx11-llvm_version+17.asserts.tar.gz/md5/b404077eea756a6c5c7bca8a54898680 -LLVM.v17.0.6+4.x86_64-linux-gnu-cxx11-llvm_version+17.asserts.tar.gz/sha512/70c562d603aa974b8143fe72ce000be60fbd975cbeee4ebd0bf29bb01bae2dcb8006e3774581d1e37fe221ea0432067d06a19e5fad963977990fdb5f1c0648e2 -LLVM.v17.0.6+4.x86_64-linux-gnu-cxx11-llvm_version+17.tar.gz/md5/1437271560c205407a4a1d72fa3d0ce5 -LLVM.v17.0.6+4.x86_64-linux-gnu-cxx11-llvm_version+17.tar.gz/sha512/463b2beede8289d4b6d3a39795fcf8e2c6007b321abdd7125cd56e2f960fb2b9c3f9e27e38cc23ccfa51ab0f9f42378f64ab8d5dd28a2ba452a3111efbd46c99 -LLVM.v17.0.6+4.x86_64-linux-musl-cxx03-llvm_version+17.asserts.tar.gz/md5/df1353b2f06a17506ef20e0315ac8396 -LLVM.v17.0.6+4.x86_64-linux-musl-cxx03-llvm_version+17.asserts.tar.gz/sha512/79a696d86252b23dbc439284f8a2dbab5da77af2541680c569cfa11bc2b4c9ac03218b6a307841ae92aedbcad88573e800ad5fc8bb1c55b957a837a7e53da592 -LLVM.v17.0.6+4.x86_64-linux-musl-cxx03-llvm_version+17.tar.gz/md5/92b15d83ee43db8522be4b4d94b8aff2 -LLVM.v17.0.6+4.x86_64-linux-musl-cxx03-llvm_version+17.tar.gz/sha512/ace2323208f16a9c53823c0ea8ad2b910d416d834e0731485008e4607ff8ed8cf566509172f8f65a8add0e7a7dd7391704246cc024eb3d40bee73f043481decb -LLVM.v17.0.6+4.x86_64-linux-musl-cxx11-llvm_version+17.asserts.tar.gz/md5/69c1c0f5f416d00a3237bf62e6c14075 -LLVM.v17.0.6+4.x86_64-linux-musl-cxx11-llvm_version+17.asserts.tar.gz/sha512/733cfafec656ac3ccb51dd444f5df028062bd1b3182463402105ae78f13675dd0dcdb79e1eacb5222d0942baaa85e487fffa01018c5c19f0f971ca96315f8073 -LLVM.v17.0.6+4.x86_64-linux-musl-cxx11-llvm_version+17.tar.gz/md5/8192a6688c46ca92ca1706fec271856d -LLVM.v17.0.6+4.x86_64-linux-musl-cxx11-llvm_version+17.tar.gz/sha512/49d602a869ba34d560966f00bf575a04516476e9c147219ef7086842326bcf88377e2c601ae22fbbe56f2a12f40d4a9611259825bfcddf05608e73b2ceb363c9 -LLVM.v17.0.6+4.x86_64-unknown-freebsd-llvm_version+17.asserts.tar.gz/md5/64b59e6cf3c0d8cf09ca4d376b298134 -LLVM.v17.0.6+4.x86_64-unknown-freebsd-llvm_version+17.asserts.tar.gz/sha512/19a1a17ad7e95ffc75cecd28be4190ed527ca5ad948995e9f3491770e010c45ec79bec52d270abeab25c96846f604b694944f2eb4dc0697f43cf4e9f86f1efb9 -LLVM.v17.0.6+4.x86_64-unknown-freebsd-llvm_version+17.tar.gz/md5/3221c8c4773ada18489016d3167ce509 -LLVM.v17.0.6+4.x86_64-unknown-freebsd-llvm_version+17.tar.gz/sha512/514a6cfbca973e95cfbbb880323056fc6b51dd373a6de26e9628801f393e42011b4c21750d0276e562ed09fcc09e9751572bb9c4f362b8972411fca3a93c8f7b -LLVM.v17.0.6+4.x86_64-w64-mingw32-cxx03-llvm_version+17.asserts.tar.gz/md5/03744874a951f038349d0179e752ee40 -LLVM.v17.0.6+4.x86_64-w64-mingw32-cxx03-llvm_version+17.asserts.tar.gz/sha512/83f34672472ed640a9e2be7eccc71fbec4d42397174dbc5abd34ffea754681c3779c07692d9eff30db299fa0c922594727f5d316ee2542baa34d081717e89ba8 -LLVM.v17.0.6+4.x86_64-w64-mingw32-cxx03-llvm_version+17.tar.gz/md5/649d1106a8f95de6eaa7835f4eb66fe2 -LLVM.v17.0.6+4.x86_64-w64-mingw32-cxx03-llvm_version+17.tar.gz/sha512/4955cb0e2850542a1116fcec9e04e7f9f6633a806013ec49fc9e519e2d511cccd375410225eb8630d74b65fe0f2633ae7f46b194db8e9ec78cf7a2f12f6920a1 -LLVM.v17.0.6+4.x86_64-w64-mingw32-cxx11-llvm_version+17.asserts.tar.gz/md5/d6a1fa15be0cde66ac32692561f2249e -LLVM.v17.0.6+4.x86_64-w64-mingw32-cxx11-llvm_version+17.asserts.tar.gz/sha512/48845cee32afe6ec3338b6abac77c773980093082d9dfedc1b9f03c31a5d940125e2c01ceaaf85d3bc06bb75e5871e24a51743b91ce1b5e8ec1c7f4eab4a4c2e -LLVM.v17.0.6+4.x86_64-w64-mingw32-cxx11-llvm_version+17.tar.gz/md5/514a676afb3bf9d5a20c52ef3f1d4bec -LLVM.v17.0.6+4.x86_64-w64-mingw32-cxx11-llvm_version+17.tar.gz/sha512/ee2ba45c86b8a4cb5d2214b9fbc488176e2134a9c19806c160bff7e3bc796991051e04fc5d2829b151faa3dca6738f4468405b246f94bdf27cb5366b1043021f +LLVM.v18.1.7+2.aarch64-apple-darwin-llvm_version+18.asserts.tar.gz/md5/341e3f0b5c160100f5e12783b8f779c0 +LLVM.v18.1.7+2.aarch64-apple-darwin-llvm_version+18.asserts.tar.gz/sha512/65b2c2091db1364adba4fe1e4ec6b9d6582432a0a0751cd0a3aa1c69798633b3aa5ff09d3de4e47d552d55d5ba81bc86662f1784cff2ed58e800452488cf9d50 +LLVM.v18.1.7+2.aarch64-apple-darwin-llvm_version+18.tar.gz/md5/249910dce0a9ee089711b71626972b26 +LLVM.v18.1.7+2.aarch64-apple-darwin-llvm_version+18.tar.gz/sha512/1eba4ecfefb56a00390e5c528c467f921d64e9ca40f5fdb4d7fe0d7ee995f03d253887f7fe40ee285f03b12fa7a194543d18cade6af8a24bf47e56b06a78d901 +LLVM.v18.1.7+2.aarch64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/7bc3125dd810bcc44ea2d454b6caa683 +LLVM.v18.1.7+2.aarch64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/86742a4476481b14145855ead8a5acc6397782f6d3445f900ac2de0570f1fcf53563cf5e1f3cb59886282083ce63756604f1ca2434e9e427cdc1bd1f68373581 +LLVM.v18.1.7+2.aarch64-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/4eae06d9e6272aef23afc191501810fd +LLVM.v18.1.7+2.aarch64-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/fb75927982b1428b05b765bd5ac017b2c15d89990b7e6cb582b9e1a3ec04d09801d25d5cc6c037a12c205edb7c0f7a2d33832a2d1de7920711e9720dc3ca3655 +LLVM.v18.1.7+2.aarch64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/cd86e18a63cd6e84a1493acf0df4e267 +LLVM.v18.1.7+2.aarch64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/1dfefc4600368467ab90ccb527a9fdb012b9b7f485d932a0db8c4b1b81985fad931b74494b76ef2162e46280447d39a055b5681b33a17c564c50094de29aeb13 +LLVM.v18.1.7+2.aarch64-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/c7cf7daa7c11827ae4f9fb2e16f3cce3 +LLVM.v18.1.7+2.aarch64-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/dabe2940606a671a8e3b4f28bb9e813d000650203c382372142457020f2ccd498534903aa99320afb7ff960a62d752ee6cb724e74745bc1bad1051e12cf78ab4 +LLVM.v18.1.7+2.aarch64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/md5/62e575b89fd92d9206abebc19b084abf +LLVM.v18.1.7+2.aarch64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/sha512/7ac029567fd68fee82b7096e2fe278ee5cd2935494433b1faace036469c54bc471d614d0bb339750429dd88f3e723165d2dacaa627f73c3647c6f3b51a4a3034 +LLVM.v18.1.7+2.aarch64-linux-musl-cxx03-llvm_version+18.tar.gz/md5/5d39ef811bc78204ebfc7e98111469cf +LLVM.v18.1.7+2.aarch64-linux-musl-cxx03-llvm_version+18.tar.gz/sha512/10fc9a64d63351e168bc79fa63bcaa6fd49c8483e5ecc40a66216192588367e9b47ec3ea2c047e88f39ea8f1caf8052726f4bc8858223f7744606156b4133970 +LLVM.v18.1.7+2.aarch64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/md5/f072fe487e5d1b717aec49a6244adf05 +LLVM.v18.1.7+2.aarch64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/sha512/42b03a2562728ac86e751abab2e8233d583baf006e69b107d002a9258844ad53f62e6332eab3790364940d478c7ebab6d3e0e2194220e8436f40e6b75063d1a2 +LLVM.v18.1.7+2.aarch64-linux-musl-cxx11-llvm_version+18.tar.gz/md5/eabf0239298f13ff4893011e75828bdf +LLVM.v18.1.7+2.aarch64-linux-musl-cxx11-llvm_version+18.tar.gz/sha512/34724d9c9a550c85d406021d7265e1848b002b8f212427eebff6e8f03ec6acc336efb0c2cd9d9e1c76329e7c84a84a9d852b8de5897550d957e0e9385129033d +LLVM.v18.1.7+2.armv6l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/1910b5daa31db6542f0c762901ab7d43 +LLVM.v18.1.7+2.armv6l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/c43e8091e9946ba1d8849734a25b258df95b4759a79676565b624930d4a19805a78b66b1d193e528f95174d909d7895d4a4e49fe8ca298a24dc40d25c95900b1 +LLVM.v18.1.7+2.armv6l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/md5/a5198b13dc75ad3454e05aa6cdaca48f +LLVM.v18.1.7+2.armv6l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/sha512/9ec8078a1a7246f1545fe074783d6b88ce9b50f62b0438ff5637f6dedf5bcac427cc252c350354b7063f79f4e31a19f699c168c15bc6547a207da497026c2827 +LLVM.v18.1.7+2.armv6l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/f569654ecdd8ec2a50986ccac8388c69 +LLVM.v18.1.7+2.armv6l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/9b50e3be1577a753f0ce42704846bd126229d8dd9f28bfcbda58c4f18e4b9ca4ec6bb9b57de61b3b9af8157a2983aeffb8af782a073e5e19a8ccc261cbea9601 +LLVM.v18.1.7+2.armv6l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/md5/496de8c9e2361f44ac6933480620d07f +LLVM.v18.1.7+2.armv6l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/sha512/02a8ecfb6e81e0fe07fb0d616a84a590e23e944588c18348c32265bf6bf19196beec189a0bc40514e379e97a9c8bef83557260839800fabe9f8e39e96689713d +LLVM.v18.1.7+2.armv6l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/05bc7406fd0a703edbc912bb3230eb37 +LLVM.v18.1.7+2.armv6l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/898dd4c19dd0f22dcd1bd44264daa8dc64340c890c3368fac7451da1ac872a687d55b5eb50ae4e156c2dc4ece226ec05775daebafe9d8b53eb83b72d2986ff92 +LLVM.v18.1.7+2.armv6l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/md5/d6ca30fc3a2796ebda2451f80846883d +LLVM.v18.1.7+2.armv6l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/sha512/d7dc96e1bbca38272b1ca78b3ff995fc30434937a58815c63d0a9b4a017964cfb269a1f3203ad8374870257152229941d420f098644375b5f4d1b88fe39e0dff +LLVM.v18.1.7+2.armv6l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/6eb1a197150ad6c165b82c5e0e0db102 +LLVM.v18.1.7+2.armv6l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/a159598c2bf351ea79d01e8a454a82bbd9823c080399520af3182e57259957ad07834b03c336e6225857da365e8ec1aa9f65b0ddd0821883ae817cb81f8e6dab +LLVM.v18.1.7+2.armv6l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/md5/116d849cb2fb4b1c8c517397b2b04192 +LLVM.v18.1.7+2.armv6l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/sha512/7b2596c76d2814fc30992ba78e5c8f93519442fa76004187de9830732b80bfc6c77f5d7aca042c20d8f868cd682bb6f71e3fa32940bc8c7b401753dc4ac2f331 +LLVM.v18.1.7+2.armv7l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/27837dc854a173bd37a20f92383f6913 +LLVM.v18.1.7+2.armv7l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/1719205cba6de969e8724a99444bf958d5a7943ae90ee2dd11193f56ddfd4f0edf6d9af6da2e67787a64b91d994fee76bd8ffde36486c5229a980c2c4ef07e29 +LLVM.v18.1.7+2.armv7l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/md5/f0016c21c045e205131ea22dc711acaf +LLVM.v18.1.7+2.armv7l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/sha512/6d192b7e21c7ee3327d288b890f4c5dd03e5f53dcba6905a34cab96b7ad0ab6364f5271af88d95e60aab8f569a8840d17e16f27f6fcdafcaf537d5d4a651dca7 +LLVM.v18.1.7+2.armv7l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/9a2bad4518966db29e37e7c88388e779 +LLVM.v18.1.7+2.armv7l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/b9a10af9dcbacf1f129d4e9b4cf562a6a4687252cc8a0fcd78f52d75c0c20be0ff32e67413a7902a628b04e7fac1091d35b64b145e33814899796009b6ed2853 +LLVM.v18.1.7+2.armv7l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/md5/77c4e24c1e44ce14bc6476954f294a15 +LLVM.v18.1.7+2.armv7l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/sha512/d9d90a4ac788dbbc1b532623a380d4cca8813ecdf8b7b4a8cfff769499e50a1433bac618234bd0765d8a4f50aafb3fa724d16ac71baf75ae5a2b4396fa2bd017 +LLVM.v18.1.7+2.armv7l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/b29e36dcf5a0aa05734f1d6a0afd6944 +LLVM.v18.1.7+2.armv7l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/ab46a835f9843c5b3427101bcd0c5d2b8acf79693aa9b8d4282d499f25df4ca248a81fc94ddd96c75d69d3c6b3814b225eed81bec32fbe9199bffdd605f7fec8 +LLVM.v18.1.7+2.armv7l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/md5/a411269f925cc968a0438562262e6d97 +LLVM.v18.1.7+2.armv7l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/sha512/04f275603134b0ea0f23da377e4983765885f2b1954d5c617134af9f103470a5e50dfda18bcddb836852db2382f1c134db40df00b36c8bd00e7a9e6ff1a9e684 +LLVM.v18.1.7+2.armv7l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/841921e33407e15eeeaa76354aa2b737 +LLVM.v18.1.7+2.armv7l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/e1fb8b75e141cc90916c5c81c31ee91336911983c525f38eab86682ba69679dfbe1f10c9b673323632fc75f38cacc2af47a3d5d5d1031ec9a2a60cebd68d501b +LLVM.v18.1.7+2.armv7l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/md5/7342a1d7b1d2c0fed7f5edf1c331ffa8 +LLVM.v18.1.7+2.armv7l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/sha512/dae8ca11fa8d34f99ee19a95bcd108a65b9e6a6ddf2e5a9b126f2ba1b1cdff6b7ec21e9590d70b3785593435bb71e47703d9765811db814a90aa8a47940421ff +LLVM.v18.1.7+2.i686-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/10aac489dfa10a77427a82958f525da2 +LLVM.v18.1.7+2.i686-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/a87f721df4fc5f6e929a54d8e41e55fb366a051a610836923213bfa42a7f1593de880391131619653cc3571bb76a4c82e011852ee5a6005523957c9f0937e6ba +LLVM.v18.1.7+2.i686-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/7f231fd359f9297261c22f95d8f738c8 +LLVM.v18.1.7+2.i686-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/fdd6441011609ef341108ff2d108c6f320d415b621a69922aeacc555c3d1ae6090a0f600f24e229a609b88ba9c1868900791a6590033b7dad333ad11f8a6365b +LLVM.v18.1.7+2.i686-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/c4523a485082044553e1a89049dc4734 +LLVM.v18.1.7+2.i686-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/db365e63bbb5189f7f348e2fd51e627ddfebf838ca9dfc6c0f8a7bbf6b8a2a03d78ea3ccdf08b0c2674f4cf5a0979506efa643554091ba751f16051bdf42ca9f +LLVM.v18.1.7+2.i686-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/bcd10e4f3e5a4b00d52441e0094de1c9 +LLVM.v18.1.7+2.i686-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/b17fae89a3dfaa9428cf48c9c0866477cc75edda6aa3800702227cc9e3d6ebaacbd60cccc96acb4ccde56a2de531dea5a436bac8e6c450a4674daae23b878037 +LLVM.v18.1.7+2.i686-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/md5/2be8cf274b7667adf8d967a27abdede0 +LLVM.v18.1.7+2.i686-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/sha512/15f58c9a00aca5bf828708089912f128adfa3b719cc2fa8b9b4cd7ff7722d02375bc9a961b02d5c6a6c9ab637b626d78876741bd824353aab944e1c3b6719837 +LLVM.v18.1.7+2.i686-w64-mingw32-cxx03-llvm_version+18.tar.gz/md5/0dce4be3e8cead78cd3d12ca0796d560 +LLVM.v18.1.7+2.i686-w64-mingw32-cxx03-llvm_version+18.tar.gz/sha512/cd60b39f2ccfca8ae0a497292819e9cc1893f6c3b2162fa9bb3136187351cfb1d6e4855141f1e9252bdee7e97ad61c0560566c2e9f73fe77a26b7f4ffadfdcdd +LLVM.v18.1.7+2.i686-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/md5/f2548c8f4bf1edb488642245221829b2 +LLVM.v18.1.7+2.i686-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/sha512/1604986526156a40ea82f50ddd0465d06df9faf306835f1dbbdac7da7f97c60fe684cd6c64acd8833a9f8b1d16f80c123ceef94fc16f255f815b93f1d41251e4 +LLVM.v18.1.7+2.i686-w64-mingw32-cxx11-llvm_version+18.tar.gz/md5/1c268e3e93ab3a34b3c05322c2fb0dc9 +LLVM.v18.1.7+2.i686-w64-mingw32-cxx11-llvm_version+18.tar.gz/sha512/f111ca82e196ea9507bb089b9d10990de1acb1a94778c40012ba6bfc16cf362369fb1f9dcc869ce14545439df21f432589ec004816a1ba0323c5edecc2b84211 +LLVM.v18.1.7+2.powerpc64le-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/b39ce0b0f143c3bef4dade99251003bc +LLVM.v18.1.7+2.powerpc64le-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/62148e1e0a31d6b28effda0a5016d9335005b27ffdc5be1d184efcbb13f13e29eca52eca19cc6800d1d0421c0e67a36027e05d5fdc967dae686b5bfd112fb2b6 +LLVM.v18.1.7+2.powerpc64le-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/9475748210eb5b1947fe3aa6673b6c29 +LLVM.v18.1.7+2.powerpc64le-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/54320295e59e5903db558b6be0220442dbaf7ea78e1612d54a35cbe014541b354ea708679da00851b962140b6da77301e27b656fd478666d3f0f710382c13a85 +LLVM.v18.1.7+2.powerpc64le-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/6a533054ccfc3d1b0920eabcfb45ee03 +LLVM.v18.1.7+2.powerpc64le-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/3871620aeea2ccaf6e4b17a675c5504624fc6d8ed57bf4e5b66e0372b7124e4f3d1e0f10baa1018d5a1ac5bc4bf0e9d2143e84827712fda1f512fed24829f1b9 +LLVM.v18.1.7+2.powerpc64le-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/3fc6d1b7d59b98823d6016f97835b7c5 +LLVM.v18.1.7+2.powerpc64le-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/745942235e40f2ab71a5eaef2768842823620d4a4dc7454a7512fb2bd95bc8a74323eec6a4b33edf1ef935151c18a20172f60fcca2fca1ff3a37b1e019ea4640 +LLVM.v18.1.7+2.x86_64-apple-darwin-llvm_version+18.asserts.tar.gz/md5/f069af39cbbb650e293093b5989324a8 +LLVM.v18.1.7+2.x86_64-apple-darwin-llvm_version+18.asserts.tar.gz/sha512/34685eccd8c1cf7b72a52bf353de16bd0cac13959584217ce5d0995b52f506909955a7051ff7b29ab9d9c3f603af8f7db936f11e4bde83f5acf16415de62880b +LLVM.v18.1.7+2.x86_64-apple-darwin-llvm_version+18.tar.gz/md5/819a9695c365b9365b6cdba7cf9288b2 +LLVM.v18.1.7+2.x86_64-apple-darwin-llvm_version+18.tar.gz/sha512/4280768862b19918e11b6a7ed09f150270e71cf4560b18b224b3591c460c9375777e73e41eda375271d719f23b211daf3ed51b3c87bf4ee4429344d14f1ed7a5 +LLVM.v18.1.7+2.x86_64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/28ae362155ce224cef605cee53e36d0b +LLVM.v18.1.7+2.x86_64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/d90f25e57f92a9da68245ceb15316e3868bf657d7e744f37cce5ccb4945777ec82fc5d470ba4fc104fe7aaabfff7b0dc260838a45331e4360b0fd14c59a55666 +LLVM.v18.1.7+2.x86_64-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/d10ec63510dc1a043ee0a4e37b49eacd +LLVM.v18.1.7+2.x86_64-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/54c393208d1f51661e631cba62a21c0685fb58827067d5ea7c42fb3d6dd8c8db99d8ee1b3c304abc25510bcb0265d86ca03e1ce19be4faa252d97cfc8a1b52cb +LLVM.v18.1.7+2.x86_64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/2c1e000206c9e7c6c8e7515eb8115e3e +LLVM.v18.1.7+2.x86_64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/12c0ead798e43448a30699b5386b3d88aac49aaef9bae283ea6d089a1c66df7293f4f220a2b5c3d96e73e556e37e745f38d81f5c68e09a86a2b19a6695eff460 +LLVM.v18.1.7+2.x86_64-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/21d6c5d5e422412b88ffce50862efb29 +LLVM.v18.1.7+2.x86_64-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/5e8e17ba79134e9752c7fbd28b62e4616574a5e1dfcb0980160a3aad28a2f6cec4e48ed1acf73ca1f94d74397f7ee3eba53cb1280699e40c451295590ede3fe3 +LLVM.v18.1.7+2.x86_64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/md5/293fdc43431493f915a3e0a5b3c6d587 +LLVM.v18.1.7+2.x86_64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/sha512/27e13a4334a3bfb3c91fd06abcc4eca7a347f4bffcbce40834302d153ef29756295121b42ac433c266668af1428ffa08ed12ce75f21fef44cd7ac1d8bdfd155a +LLVM.v18.1.7+2.x86_64-linux-musl-cxx03-llvm_version+18.tar.gz/md5/2825dac8280d0563b7f521a9eb8c0563 +LLVM.v18.1.7+2.x86_64-linux-musl-cxx03-llvm_version+18.tar.gz/sha512/7f4549ac7b63e58d8c149f6b22bd997545713477a1df3b32adf640f3951580df1645f08756d9ba80c479160cf5759e3f9372396655a35cdca14f4be4afc4ae22 +LLVM.v18.1.7+2.x86_64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/md5/0c0da0eccec4a092fc0e9a915716ed6f +LLVM.v18.1.7+2.x86_64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/sha512/e538e29c4d52d9aaf151670619702541fed8231ae4c7fb9431a425d10eea95433087034a37da8fe468bd27a1c882f6f8eb9549ef71964124db10e99f4b402ba5 +LLVM.v18.1.7+2.x86_64-linux-musl-cxx11-llvm_version+18.tar.gz/md5/6b4fd19277c978306441da3b58ab86a1 +LLVM.v18.1.7+2.x86_64-linux-musl-cxx11-llvm_version+18.tar.gz/sha512/6216b3e1dc6aea979d8b5abc4cc0faf510e4e64441b1d18b4b36c45d65e874e9046e14eea67efb88f3219449ef048d34fcb751b15c59f8a299aa822b426d50ae +LLVM.v18.1.7+2.x86_64-unknown-freebsd-llvm_version+18.asserts.tar.gz/md5/b7956d25e0e5ced19df637b4fadaa532 +LLVM.v18.1.7+2.x86_64-unknown-freebsd-llvm_version+18.asserts.tar.gz/sha512/ad632493095a8fc3638ff48514c9902215378532c1455cb19d70da9f2ae46fdd91ad4a8b5a3151bedd38dda9f07c21f9a25d8e095ded7ba843f9bbeb005e1bd4 +LLVM.v18.1.7+2.x86_64-unknown-freebsd-llvm_version+18.tar.gz/md5/392f0f0f61fb672002c7473c64a63ccc +LLVM.v18.1.7+2.x86_64-unknown-freebsd-llvm_version+18.tar.gz/sha512/d620dcee0b20e3aa4b2fcb7ae835933b33b5e4c4b5d9102b885c70b1dcec535239eb5a3d6b56b51f7b049943a2c79950bcd4a4425610f7a1531f6c452eac03bb +LLVM.v18.1.7+2.x86_64-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/md5/0b41650067323bbe0c5edd5c060b517d +LLVM.v18.1.7+2.x86_64-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/sha512/111a21a5b491a77c69ee724b37d15b0c7baea387bb6a36695a1c2dd5f6e2eedb0ed211513145d8a6ce4dd6329b2de67e9bfce1b03fbf911b906a33a39e573f9a +LLVM.v18.1.7+2.x86_64-w64-mingw32-cxx03-llvm_version+18.tar.gz/md5/a9079da821bee8e4b5aebf47a46cd9f8 +LLVM.v18.1.7+2.x86_64-w64-mingw32-cxx03-llvm_version+18.tar.gz/sha512/7088945264d1ccead492e81636086390fad91b0e071e9f3a54ef903b619ac2a7bd38fa5e0e04ea1e299f3985e04838cd5b7a2dffd666b8e7dbbf3b419f74df88 +LLVM.v18.1.7+2.x86_64-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/md5/4ccb3d0eabf8253cbdc1192b04c78d4f +LLVM.v18.1.7+2.x86_64-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/sha512/9d817068dcc2b60c77fa639aa7632cbf071746e7dba62fe524c095f86e88b9323c3ab82ed5af0dc8b1af9c3e6f0da18be53d92e7c05e2d056c84e5a4e974b6d8 +LLVM.v18.1.7+2.x86_64-w64-mingw32-cxx11-llvm_version+18.tar.gz/md5/a88f7a9f42d2cb5567c84d7fa2a2732d +LLVM.v18.1.7+2.x86_64-w64-mingw32-cxx11-llvm_version+18.tar.gz/sha512/9b16cbf75e9971dd4950cd79aef85396a7d8522a572f1c8017af82725cb335674741af680e1dd10c731987a321d3afd5e3e85718d3c3fdd1c9de4803e72a66ac LLVMLibUnwind.v12.0.1+0.aarch64-apple-darwin.tar.gz/md5/b95ad4844e649bf46db43683b55b9f4f LLVMLibUnwind.v12.0.1+0.aarch64-apple-darwin.tar.gz/sha512/15e0996aebe6db91fe58121001aa7ea4b23685ead3c26b5d89afae34b535e34b4e801a971f4854d8e1a1fbc805cece06272470622eef863e225358113a127913 LLVMLibUnwind.v12.0.1+0.aarch64-linux-gnu.tar.gz/md5/6d8783dc9b86c9884e0877f0d8ac4167 @@ -138,115 +138,115 @@ LLVMLibUnwind.v12.0.1+0.x86_64-unknown-freebsd.tar.gz/md5/54ac594b4c8e7f261034a8 LLVMLibUnwind.v12.0.1+0.x86_64-unknown-freebsd.tar.gz/sha512/a43756afd92081e6dd7244d162862fc318b41ca110a5e8be6e4ee2d8fdfd8fb0f79961ae55e48913e055779791bd1c0ecd34fd59281fb66b3c4f24a1f44128f0 LLVMLibUnwind.v12.0.1+0.x86_64-w64-mingw32.tar.gz/md5/83cf8fc2a085a73b8af4245a82b7d32f LLVMLibUnwind.v12.0.1+0.x86_64-w64-mingw32.tar.gz/sha512/297a5c7b33bd3f57878871eccb3b9879ea5549639523a1b9db356b710cafb232906a74d668315340d60ba0c5087d3400f14ab92c3704e32e062e6b546abf7df6 -libLLVM.v17.0.6+4.aarch64-apple-darwin-llvm_version+17.asserts.tar.gz/md5/1b99f43b611f8c72e187b767adf8abf6 -libLLVM.v17.0.6+4.aarch64-apple-darwin-llvm_version+17.asserts.tar.gz/sha512/e8a65c950e1d782ab6fca6da5b9ce434a66901d7c1efac0ad973cc376ea1c6d1ce7d68802d623b66d9fdd2801035383a11961cf544173a54e90b6cc4acc2ff88 -libLLVM.v17.0.6+4.aarch64-apple-darwin-llvm_version+17.tar.gz/md5/7a1171e54395fbf5742c0b3dcb1ad116 -libLLVM.v17.0.6+4.aarch64-apple-darwin-llvm_version+17.tar.gz/sha512/f173b4fd6090cfddb2fe43da5603d7eb627bd8cc1385b039a719b830fd82f230d0e1e7e9d8808c94cebb83c46145148c206e4dd43cb5cafb96d7995f116a170e -libLLVM.v17.0.6+4.aarch64-linux-gnu-cxx03-llvm_version+17.asserts.tar.gz/md5/0564e41ee1ea590661214ed7747fba62 -libLLVM.v17.0.6+4.aarch64-linux-gnu-cxx03-llvm_version+17.asserts.tar.gz/sha512/8be4f721f5d6f264f4934423fa884e43ef6fda5f895786ecdad51bfdd3c02df575a84be87d69a367cdd4131576558096502b77063d766a3961be1f1b4ab8e205 -libLLVM.v17.0.6+4.aarch64-linux-gnu-cxx03-llvm_version+17.tar.gz/md5/d64714dcc951dddf20423aa7831cff9b -libLLVM.v17.0.6+4.aarch64-linux-gnu-cxx03-llvm_version+17.tar.gz/sha512/41bfd5c44c27be4538a19da87bab09f35cb7212eb31205cac876c35721a15b6baba26ae52b5457f9db2e4f51e9600cf9677c68a6adb6385d1fc07fe7edec274b -libLLVM.v17.0.6+4.aarch64-linux-gnu-cxx11-llvm_version+17.asserts.tar.gz/md5/f457fb97ed50a72dfc59a3e84177afa1 -libLLVM.v17.0.6+4.aarch64-linux-gnu-cxx11-llvm_version+17.asserts.tar.gz/sha512/a04ef467f8761843c6e621e5d996f9cbf06d11d46c6b7bf85cddd768ec7ee1a6374caf153afb8a5c017048266e6b5df6c5d90cdfd99f1ca0f2e096002e2c0d4b -libLLVM.v17.0.6+4.aarch64-linux-gnu-cxx11-llvm_version+17.tar.gz/md5/4f6544a9c3e3e4929ccb5f53d5be47b8 -libLLVM.v17.0.6+4.aarch64-linux-gnu-cxx11-llvm_version+17.tar.gz/sha512/cce7cc5eaceff2f02e67258fbade6aee130462d049d1948c37061018f9acccfb4bfbb0cf8f751da83c8f76fc504ecd4ea9afe16382e4d9f261c573a1daaef942 -libLLVM.v17.0.6+4.aarch64-linux-musl-cxx03-llvm_version+17.asserts.tar.gz/md5/137328448b1a47a3ef13cca0665356f7 -libLLVM.v17.0.6+4.aarch64-linux-musl-cxx03-llvm_version+17.asserts.tar.gz/sha512/0e6ad105e6cf8ba21a7521ba213e3608679e414740cccc03fbc33385310b50637da9a8c1cb0ac3b54e0ed487e04e3e0557cdcac40d25211731645ee1c56aa238 -libLLVM.v17.0.6+4.aarch64-linux-musl-cxx03-llvm_version+17.tar.gz/md5/412efb53b9468fa5a64866c76a60d9ab -libLLVM.v17.0.6+4.aarch64-linux-musl-cxx03-llvm_version+17.tar.gz/sha512/8c02a1d910aacf807f8920a930ea52ef423d70a6ddb18eaab32ec14e836e08b50d2444fde6832f5eff21bc14ca291d69a2968d6bc94e4039dc439b879378bd3f -libLLVM.v17.0.6+4.aarch64-linux-musl-cxx11-llvm_version+17.asserts.tar.gz/md5/56445a46ec24a4ccf796b42d83a5b43e -libLLVM.v17.0.6+4.aarch64-linux-musl-cxx11-llvm_version+17.asserts.tar.gz/sha512/90549dfe474c8ed9b12b4589243d53508b2b682f71061d583b77a01131fd215341f8dd860609823c5a564c5dd61b317c844b9d050920e19a99daf3d024f937cc -libLLVM.v17.0.6+4.aarch64-linux-musl-cxx11-llvm_version+17.tar.gz/md5/48d268feb53cccc7b12700a172793525 -libLLVM.v17.0.6+4.aarch64-linux-musl-cxx11-llvm_version+17.tar.gz/sha512/a6fbfc44d5382de86548ecdf7d18a8487ad37c84efe79d67d9360872dac756e7e013972981c97758a7a9eb3857d70d79d3b8bc90aaf1638ddd8c456111507ec0 -libLLVM.v17.0.6+4.armv6l-linux-gnueabihf-cxx03-llvm_version+17.asserts.tar.gz/md5/17986258a97407361b4c4c3679932666 -libLLVM.v17.0.6+4.armv6l-linux-gnueabihf-cxx03-llvm_version+17.asserts.tar.gz/sha512/71fc532446f5b20f2118a56b412690ed38c3bfc52d3e52079dd903b671bd4624e2125f377c183b86aea4ba57592ba9a1143b5a1327ce49b128bb7c81490305ab -libLLVM.v17.0.6+4.armv6l-linux-gnueabihf-cxx03-llvm_version+17.tar.gz/md5/dc7d7b2e6184a1ecaf433a2589b59940 -libLLVM.v17.0.6+4.armv6l-linux-gnueabihf-cxx03-llvm_version+17.tar.gz/sha512/d14b4b583dcfd8709e17d7ac79ebb5cfb044480a85591b5e26b8fce9ecf49a13c4b562ad6e6d2081366db86e6b66caed2278ef167a97650104fb818b5b0e4776 -libLLVM.v17.0.6+4.armv6l-linux-gnueabihf-cxx11-llvm_version+17.asserts.tar.gz/md5/d6c4ac2506639735cd7bb4940404806a -libLLVM.v17.0.6+4.armv6l-linux-gnueabihf-cxx11-llvm_version+17.asserts.tar.gz/sha512/2089a09a4ba75fdaf053c4a59b3a5cd333c6e043f9e5bab186d5d751aa84d616dede56799468768190b3b8120747e7e08d404b8c39e7329b3154ae134ebbcdd3 -libLLVM.v17.0.6+4.armv6l-linux-gnueabihf-cxx11-llvm_version+17.tar.gz/md5/20dadbec0c7ce386f718031adbc21b9a -libLLVM.v17.0.6+4.armv6l-linux-gnueabihf-cxx11-llvm_version+17.tar.gz/sha512/2a6f09158272ba3d2a332646db57a94c2b9481835a974ec87f4c9ff23b5e5dfd6030f71d98a43380fb5bde078d7fb586cd5afc75b4b4428ae80f6dd09dbd26b9 -libLLVM.v17.0.6+4.armv6l-linux-musleabihf-cxx03-llvm_version+17.asserts.tar.gz/md5/9508999ae1be9c15f87ac49eef8bae80 -libLLVM.v17.0.6+4.armv6l-linux-musleabihf-cxx03-llvm_version+17.asserts.tar.gz/sha512/735e5cee32590cb1360ed760d49357b2fdc830f943e3c184ba9c213f620ee38b4b8d7dc378540fbefd0f500c61a131b36051834ce521bb6d75f0c6ba7e223606 -libLLVM.v17.0.6+4.armv6l-linux-musleabihf-cxx03-llvm_version+17.tar.gz/md5/0c56726d3c7b249621c7e5e71bb91660 -libLLVM.v17.0.6+4.armv6l-linux-musleabihf-cxx03-llvm_version+17.tar.gz/sha512/843062aa01605beb40f2d5a484638fa4b896016cca242084ce74d4a5eb1c0b8fc91addd71be105a784e083b90b328d0c9fdfdfabb0d257bb91d5ada5f4f71988 -libLLVM.v17.0.6+4.armv6l-linux-musleabihf-cxx11-llvm_version+17.asserts.tar.gz/md5/3674c019b88c8324c78343cf45beb98d -libLLVM.v17.0.6+4.armv6l-linux-musleabihf-cxx11-llvm_version+17.asserts.tar.gz/sha512/043faeafccd4bfb5207078af3517832ca710add36eaebf8abde86e4801c1e964d3bad5547800ed5fc4722b90c2bdd606a11ca06ab277f1e48264a194b1cf85c1 -libLLVM.v17.0.6+4.armv6l-linux-musleabihf-cxx11-llvm_version+17.tar.gz/md5/bd94929dcafc7ef8d4ad1f788023afa2 -libLLVM.v17.0.6+4.armv6l-linux-musleabihf-cxx11-llvm_version+17.tar.gz/sha512/26b40bad7ac61366e5609c6078d2ec34bc18ef89b25d0c251a6dd49e83df4a62338f49cae2729d245a1d367a9d7bde01a286eefbc71668097d83b4c98402fab6 -libLLVM.v17.0.6+4.armv7l-linux-gnueabihf-cxx03-llvm_version+17.asserts.tar.gz/md5/0a443c1b7289030b32e22dc137b4ff3e -libLLVM.v17.0.6+4.armv7l-linux-gnueabihf-cxx03-llvm_version+17.asserts.tar.gz/sha512/6ad96be0acdbc90ac092130ff438a1bd0df409683df624e0fce4095bf393ca90c54c71c19b1dc1a28563a25ea06f35d7883f199533d3e52ab42bc373212aed9e -libLLVM.v17.0.6+4.armv7l-linux-gnueabihf-cxx03-llvm_version+17.tar.gz/md5/5ada2da7581d128ec2dafed8ddd489d4 -libLLVM.v17.0.6+4.armv7l-linux-gnueabihf-cxx03-llvm_version+17.tar.gz/sha512/6b9d41908dd882e7a874a46786f5bf67db1d63c2917a91119dddbbf01bd709ec5d2487c0f3703e669a7ef404fd1a5a7c8671e4ed2e3fd10a47e6c4f6c2b7f115 -libLLVM.v17.0.6+4.armv7l-linux-gnueabihf-cxx11-llvm_version+17.asserts.tar.gz/md5/86074d6b9a30cd8b6ffd8e1e1b3a6d62 -libLLVM.v17.0.6+4.armv7l-linux-gnueabihf-cxx11-llvm_version+17.asserts.tar.gz/sha512/48c7d92a780841d333adda21984920ca66d47b54b152c4316dac05bbb6b8ea6007644cf93b4a4f8475a4cb5a228dd0d0cc17482d873c7d9c9d90213b64c3ccc8 -libLLVM.v17.0.6+4.armv7l-linux-gnueabihf-cxx11-llvm_version+17.tar.gz/md5/df1fcdc1f7f385fe630bbc83f121943f -libLLVM.v17.0.6+4.armv7l-linux-gnueabihf-cxx11-llvm_version+17.tar.gz/sha512/8c1a8fd4665c871d50e68249453918f865429cb9d3fece6ee139f367d006d5cc21613681e84656f9cc4bc6e884b3de7c19c808fe9dc2a9c7ca8b1ea9aa594e6c -libLLVM.v17.0.6+4.armv7l-linux-musleabihf-cxx03-llvm_version+17.asserts.tar.gz/md5/07b634f82a8330440a2d5608cfa90c42 -libLLVM.v17.0.6+4.armv7l-linux-musleabihf-cxx03-llvm_version+17.asserts.tar.gz/sha512/51cbc0753da4612ffd8f3f50c2536e7cb26d6cc67c3b936f2f971cceb9735b9e587dcbe88dde32367c9b581fae639bbe8076b774b6135288f2b160719dd97735 -libLLVM.v17.0.6+4.armv7l-linux-musleabihf-cxx03-llvm_version+17.tar.gz/md5/26261c713ecceb1d7a076c784d76bc0f -libLLVM.v17.0.6+4.armv7l-linux-musleabihf-cxx03-llvm_version+17.tar.gz/sha512/64344d21f38858d4a10adadc169c03ff98d523937882c8244f297d5e835ec8186eb8ad20e54c4aa5bed597af35e7b25cb2499607c967bf404054084715d631f7 -libLLVM.v17.0.6+4.armv7l-linux-musleabihf-cxx11-llvm_version+17.asserts.tar.gz/md5/24ed4293f7fab2172ab21b96fb44817a -libLLVM.v17.0.6+4.armv7l-linux-musleabihf-cxx11-llvm_version+17.asserts.tar.gz/sha512/d3c612c24e4a3159699ba5e31d51c9068e977780f3ff2af49a1b084af707398e51756921eb0fec7103bf99e80b6beac4cff5c1bb32c72920ec0834be7929b33b -libLLVM.v17.0.6+4.armv7l-linux-musleabihf-cxx11-llvm_version+17.tar.gz/md5/6e53ecf916b54f97f0aa6fdabc49e9d4 -libLLVM.v17.0.6+4.armv7l-linux-musleabihf-cxx11-llvm_version+17.tar.gz/sha512/8ceff63d6ef095dc2db7d836871bb07ba8d36bd946938a21dcff9edc8531635df8af1ce0b39fee0fd644929ab14d127badc77697a559fdde2233d2a74ade6282 -libLLVM.v17.0.6+4.i686-linux-gnu-cxx03-llvm_version+17.asserts.tar.gz/md5/122aef0ec2c01128acd1b830faf9e279 -libLLVM.v17.0.6+4.i686-linux-gnu-cxx03-llvm_version+17.asserts.tar.gz/sha512/b163e80b21a91b75f8c7a82a3cae705bf1dc6b9f4243ff0e5ebed535589ddea835b3071c36794ca8511b411c71b545a9c3eb75f0a530e682996922916e2bbf5e -libLLVM.v17.0.6+4.i686-linux-gnu-cxx03-llvm_version+17.tar.gz/md5/8410e6b787a1a39cbcdfefbc69ffc0a0 -libLLVM.v17.0.6+4.i686-linux-gnu-cxx03-llvm_version+17.tar.gz/sha512/debda3ddf24fe3228ac3f90f809aa4c3479a4d46a61f5aafb609740d353acea80cc33086e5fc79303845a642c4171c7da79108a213728630e5045daf18e0d6e9 -libLLVM.v17.0.6+4.i686-linux-gnu-cxx11-llvm_version+17.asserts.tar.gz/md5/7d34ab481b9b538feb96f53c5c0d6305 -libLLVM.v17.0.6+4.i686-linux-gnu-cxx11-llvm_version+17.asserts.tar.gz/sha512/2af919b8481c1531b9a2458dc80fddedf3bbc0eb9d70a4ba7b6b1ac5bbf1163b3c407a026fb95d5c580687ced6bfa7ab474efe91575c9d3d98e3801e1d64af99 -libLLVM.v17.0.6+4.i686-linux-gnu-cxx11-llvm_version+17.tar.gz/md5/26e92a8a602bad11d07e5e28dc597363 -libLLVM.v17.0.6+4.i686-linux-gnu-cxx11-llvm_version+17.tar.gz/sha512/f6ceb5ff769b7fe75e19ea10fb3ddef55517228526e6fb3d961faa8e776e7b3cf3d62536cf1f287a4d0d9054c9e7b92181b7e3dd8ecc1d0f79bdc585f2008d37 -libLLVM.v17.0.6+4.i686-w64-mingw32-cxx03-llvm_version+17.asserts.tar.gz/md5/14025c82e278f11ce31fd115c6e8c344 -libLLVM.v17.0.6+4.i686-w64-mingw32-cxx03-llvm_version+17.asserts.tar.gz/sha512/161f80c5d1289a90cab305bc6dc6a54528e797e6a0be375afba819640507df76636885b9aa5378f2585a7441acad50566004f437ce1e872e50e8c7385fcf4621 -libLLVM.v17.0.6+4.i686-w64-mingw32-cxx03-llvm_version+17.tar.gz/md5/47ebe4003cf9938930d992d12c52e6a5 -libLLVM.v17.0.6+4.i686-w64-mingw32-cxx03-llvm_version+17.tar.gz/sha512/0d3ca73be07d98bec4f283e84c4286249de7ee8f2b9cae7c1b0f44a96ef9d90fd16e3911c9fd49652e0fcd105cb2588d66994aa502e9b3a7cf22eed6f264c6b5 -libLLVM.v17.0.6+4.i686-w64-mingw32-cxx11-llvm_version+17.asserts.tar.gz/md5/91d359c70756f364192ae99a3078773e -libLLVM.v17.0.6+4.i686-w64-mingw32-cxx11-llvm_version+17.asserts.tar.gz/sha512/a2c36c4039e98b06472a4081621cca4352bf0050d915a3d28e93185f16e85fc38305079a94d13870422feb9e5c365219d9213fc64441d1f9f2dc176711447282 -libLLVM.v17.0.6+4.i686-w64-mingw32-cxx11-llvm_version+17.tar.gz/md5/56857016759f1e7a7414d41b65756d20 -libLLVM.v17.0.6+4.i686-w64-mingw32-cxx11-llvm_version+17.tar.gz/sha512/e136529b357eb9cf6659f8b0447bc63bce77e3f0b943e955c01571b69184fb0c326b08effdb9e08342556c3b8649603d94e8c9c265041482e2c103b582f102da -libLLVM.v17.0.6+4.powerpc64le-linux-gnu-cxx03-llvm_version+17.asserts.tar.gz/md5/ba23feb343b22ea60d9e1ffa0d4093e8 -libLLVM.v17.0.6+4.powerpc64le-linux-gnu-cxx03-llvm_version+17.asserts.tar.gz/sha512/84b77313f0048e02b7e4d6185a47417e66ec6f32ba2a8e9029b688a386acd3c19c84b1bf351e2ab6ef7942101f1fd89402bd12bf4676d126cb1b283ce9272d0e -libLLVM.v17.0.6+4.powerpc64le-linux-gnu-cxx03-llvm_version+17.tar.gz/md5/5bcdc7a767e191726714edc8ca6a416c -libLLVM.v17.0.6+4.powerpc64le-linux-gnu-cxx03-llvm_version+17.tar.gz/sha512/fee08e6b046128c83932160a376dec01666c10dcbc22584177c017ccefc7201147c74c12137213c8209db8f0ea04102628c47dbc9a51615db889afb0cd11abdc -libLLVM.v17.0.6+4.powerpc64le-linux-gnu-cxx11-llvm_version+17.asserts.tar.gz/md5/526db12f2f2238cbf935f7a2bb7c2485 -libLLVM.v17.0.6+4.powerpc64le-linux-gnu-cxx11-llvm_version+17.asserts.tar.gz/sha512/38602341b0e5f1ab99af66cbee19c0587beeb7883c71ac9b3a7c5853a09fe1b4aef9afc6ec66fc53442e491c976f02dd5dbc739ee9974689af5f76396f2ad382 -libLLVM.v17.0.6+4.powerpc64le-linux-gnu-cxx11-llvm_version+17.tar.gz/md5/6837b6aa15a9628614b046c18985dba0 -libLLVM.v17.0.6+4.powerpc64le-linux-gnu-cxx11-llvm_version+17.tar.gz/sha512/4fccea20fc1bf221b27193a85fb3b274c4479c6f9b5c8e77fd9666f053b051785e7b4bf512466a0e6df5c303316825523c634b3c81e7829824b3e6fa28b4f032 -libLLVM.v17.0.6+4.x86_64-apple-darwin-llvm_version+17.asserts.tar.gz/md5/0ba2cb738f9e3f1cbcd0774331ffb7fb -libLLVM.v17.0.6+4.x86_64-apple-darwin-llvm_version+17.asserts.tar.gz/sha512/5a6de296017d942e7ec108663fe238f7bcf2a0db54d9cc3c44f4b2fd2596f2d4641d5ee1ea183d0b6cfd3bf10a4d1196c21a503f89f8c1c3746023e5558c6049 -libLLVM.v17.0.6+4.x86_64-apple-darwin-llvm_version+17.tar.gz/md5/53cbd7116db0d09ef0e41802032b8d3f -libLLVM.v17.0.6+4.x86_64-apple-darwin-llvm_version+17.tar.gz/sha512/30cd95f1437fd05a73965e88d35e3c91d4281ba9a339d04a36d8450576e8f32eb1b7325b45b8c979ca63b319af582c49f867a7507248dd1f3567226c9fe29c6e -libLLVM.v17.0.6+4.x86_64-linux-gnu-cxx03-llvm_version+17.asserts.tar.gz/md5/d9d5f588ff478450645c99a6fcbc59df -libLLVM.v17.0.6+4.x86_64-linux-gnu-cxx03-llvm_version+17.asserts.tar.gz/sha512/b0320e945024bd3519edd48dbfac8735a6f6041c199bd78db345f27ada53bc12917184350a9448b12d4f2ebd594e0e1aacc12c7796807abfe47997f38db21c9e -libLLVM.v17.0.6+4.x86_64-linux-gnu-cxx03-llvm_version+17.tar.gz/md5/8e79c58d7ee18853107954d97d19afac -libLLVM.v17.0.6+4.x86_64-linux-gnu-cxx03-llvm_version+17.tar.gz/sha512/eafed326babfd8ab56dc75c999b7526729723d20a343c98125a532ad35bc3ef1cecacc8366679190dfb96b7be6617adba614011e87d925032c5dfe96172b9228 -libLLVM.v17.0.6+4.x86_64-linux-gnu-cxx11-llvm_version+17.asserts.tar.gz/md5/da04c26d8cfd0dc3487bdb28c5641673 -libLLVM.v17.0.6+4.x86_64-linux-gnu-cxx11-llvm_version+17.asserts.tar.gz/sha512/5b61115f20383e0c0c7274e24091d6e8ac29961aba5ba5a81c4f8d1226b969674d72642627125fac696b6dfbf64cbad7aab1f090bca217b8df4f50148c20442c -libLLVM.v17.0.6+4.x86_64-linux-gnu-cxx11-llvm_version+17.tar.gz/md5/0283786c2b0901e9e5893179c29c6cb3 -libLLVM.v17.0.6+4.x86_64-linux-gnu-cxx11-llvm_version+17.tar.gz/sha512/f47ebfc5acd36940ea64d5fe5d3bd69aee430c911c58b453a2355b55690b488adc032437bd10f893afce1da5f8777ca5446426dd506b8b5fc9fb6f76fbf9f6f9 -libLLVM.v17.0.6+4.x86_64-linux-musl-cxx03-llvm_version+17.asserts.tar.gz/md5/aa8af3906a48929dfd6c04a83d909eac -libLLVM.v17.0.6+4.x86_64-linux-musl-cxx03-llvm_version+17.asserts.tar.gz/sha512/ef9954203c7f3ed81e044c44ca80374485b91551267a5b74bc42c4fddf82ebdd7f4136dcd22b05d70bb66ae47d4ed49079f5e83f38f0a7b9141158d631f96c9e -libLLVM.v17.0.6+4.x86_64-linux-musl-cxx03-llvm_version+17.tar.gz/md5/26cd3622c65ceff6a74191395bcec31b -libLLVM.v17.0.6+4.x86_64-linux-musl-cxx03-llvm_version+17.tar.gz/sha512/033cb0f0ddc9027afb5dace0ecb39b3be9f13badda715fea1f8f04ab969f0a7b25544849abe851f4aac2576f4d99c9be8595296e8d1b7cc4accfd4cc3c882b3a -libLLVM.v17.0.6+4.x86_64-linux-musl-cxx11-llvm_version+17.asserts.tar.gz/md5/a2fc72f59c1cdd2042b855c833e23c1b -libLLVM.v17.0.6+4.x86_64-linux-musl-cxx11-llvm_version+17.asserts.tar.gz/sha512/0fc74b666b91d667fc112f38b970bca4cedc3083fa832907d9daddbf7cf99fee89ea42829eda609bd96a1bc9d80adaf32b047232a71c5957b87fef60cdd4c046 -libLLVM.v17.0.6+4.x86_64-linux-musl-cxx11-llvm_version+17.tar.gz/md5/91d0f5839e7e744eb8048793c3236a89 -libLLVM.v17.0.6+4.x86_64-linux-musl-cxx11-llvm_version+17.tar.gz/sha512/da9ef48726b6d4e2012831bc246e3e6d2401af7ddc7636add6c96239351a36c3c5ae2fa71937b047ba0f63eb0377692ae85357c2be0a73ab6e5e710193266bed -libLLVM.v17.0.6+4.x86_64-unknown-freebsd-llvm_version+17.asserts.tar.gz/md5/6942c1fc5ba689e7058100a6b0fce16f -libLLVM.v17.0.6+4.x86_64-unknown-freebsd-llvm_version+17.asserts.tar.gz/sha512/8919f5b643aaa6c6c761d92b4e3d6d28165e18edd75baf2ed1dc32b27c1b2da55f71b6dd5ba7d114d021993eb4db415e8ae264ff014a12dcfad78543c510dea3 -libLLVM.v17.0.6+4.x86_64-unknown-freebsd-llvm_version+17.tar.gz/md5/1a91e2eb0b4d4f6d691d552e78060661 -libLLVM.v17.0.6+4.x86_64-unknown-freebsd-llvm_version+17.tar.gz/sha512/f1a1e2c1ef51bfe489660e2a1b1c997f550cddb8bf09634cbdfc6c17bb0a1d6096ad94fe92e02cc5bf61e6b4bbf4d3a91704e9c15e672f5f3ab4a9766257d395 -libLLVM.v17.0.6+4.x86_64-w64-mingw32-cxx03-llvm_version+17.asserts.tar.gz/md5/c9d70905fe2dfde034855eab75d10339 -libLLVM.v17.0.6+4.x86_64-w64-mingw32-cxx03-llvm_version+17.asserts.tar.gz/sha512/58e653a04f75078767de6d4a65086eca681f27d4c579fee518ae974d47252699bc217a150c5e688f69d7444670a3812ad0edebab2886a5c4ce501d2570e38cda -libLLVM.v17.0.6+4.x86_64-w64-mingw32-cxx03-llvm_version+17.tar.gz/md5/c7342d2bc6f0004c78b8e768da06d332 -libLLVM.v17.0.6+4.x86_64-w64-mingw32-cxx03-llvm_version+17.tar.gz/sha512/c1736f186925c7c21a97570b0346ca235d20651f7329ecd4142737473ce67b98a36434c02b384e3b698990238b6118f164601af5d91895bbfcab69397bc6b85f -libLLVM.v17.0.6+4.x86_64-w64-mingw32-cxx11-llvm_version+17.asserts.tar.gz/md5/a90df960291596424b7291a68f632404 -libLLVM.v17.0.6+4.x86_64-w64-mingw32-cxx11-llvm_version+17.asserts.tar.gz/sha512/ee002ab1b08078d02b5f1624ad2b6590d1937ee4c7d0c78b03b6dab8c7906d46f5373b8d5fbb76460ed8782ed85c84b12ac4b139a84bc73d2c17064930a668c6 -libLLVM.v17.0.6+4.x86_64-w64-mingw32-cxx11-llvm_version+17.tar.gz/md5/e1928993bffba68c277f7bf6e1f537ad -libLLVM.v17.0.6+4.x86_64-w64-mingw32-cxx11-llvm_version+17.tar.gz/sha512/c18ee72b3187b1bb5184e5047164338d2a52eec626db44a09a77c23889db8a39e417020f3c50feea0f180aef39f2f23fff4d3324fa7030e4feef6a4033fc4c70 -llvm-julia-17.0.6-4.tar.gz/md5/3c69462bf7ba6219955dbc9e7e0c52ab -llvm-julia-17.0.6-4.tar.gz/sha512/aa96b3d01d3c2c86b79712a13f1abaee8dc95b63c8c7733588c2d5709bb72e2e835909af5a907c77b5d99d69ec69f97cf567d706d11d5f54d4c6b8536fc7762f +libLLVM.v18.1.7+2.aarch64-apple-darwin-llvm_version+18.asserts.tar.gz/md5/2ea6046caf5a3d519ab1c3309a2eea31 +libLLVM.v18.1.7+2.aarch64-apple-darwin-llvm_version+18.asserts.tar.gz/sha512/079720b30c61ded8499eefdb314477d58bd121e9f326d98696ee39b2ed91f806d5f67e68b6fbef8613a992175fe34694e5efe83e87ef3bfbed67d6b7fc41ebf9 +libLLVM.v18.1.7+2.aarch64-apple-darwin-llvm_version+18.tar.gz/md5/62c49bc7767d1ff114dc6b6a996449ae +libLLVM.v18.1.7+2.aarch64-apple-darwin-llvm_version+18.tar.gz/sha512/c708472b325cd73b94e10003bf3267b0ecbf3627072302fb22e78336974f2c7855c8597420efc954bca30aee17cec55277aa0c95a01cfff38d5d77df50c807f7 +libLLVM.v18.1.7+2.aarch64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/766a2de98d275877bb676ff1f23e972f +libLLVM.v18.1.7+2.aarch64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/3b353ea038fafefc13ccb4a81c7242d569c206362605be374fb312cb495f385796d052c3a7e08c7fe6ecaa3018e2a7e3dfa43d71a8c3a94987f7dc7aa378fd22 +libLLVM.v18.1.7+2.aarch64-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/0684a6b210b799a8a0f45a286f3dfcc5 +libLLVM.v18.1.7+2.aarch64-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/4221e2d74117bd7e89aba2945030c1507e51999b236814fd23036565364c328392e87032daf1b9fe274ed89fcf9a6dcd203f0f1c8602c2a08d3fcfa189a5fefe +libLLVM.v18.1.7+2.aarch64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/6b460256e923637e5107d67859eb60ba +libLLVM.v18.1.7+2.aarch64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/7d3f2736afe4022842529b1355cf9914b7a1c7b1e261f814a4523ad30a0cf0189056d5117a06720bbb7a844a435bb632ddbda2daadbf7e01c0120452cd13e6a3 +libLLVM.v18.1.7+2.aarch64-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/c2b13a6a296adbb4be91dd3bb5be0877 +libLLVM.v18.1.7+2.aarch64-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/9086937e718125afd535b0066ee08a3523161a94fa7ef3c9a3e86bfe760f251b6ea7b035888e61a0e7f192ed25c9bd0f4dc153df86e08569e7067a7a30ba48c5 +libLLVM.v18.1.7+2.aarch64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/md5/758d33fe0b2b3d0371708614365450e8 +libLLVM.v18.1.7+2.aarch64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/sha512/79a662f72ba1b89b373d1d143ee880a12cb128211e79182e7befe8b3e50298b594de2ce489ca8bcdeadb17fceee811622f8bfcbc3e232cefdaf9927177469eec +libLLVM.v18.1.7+2.aarch64-linux-musl-cxx03-llvm_version+18.tar.gz/md5/2dcbb811be8985bfed3c8b37733c0d40 +libLLVM.v18.1.7+2.aarch64-linux-musl-cxx03-llvm_version+18.tar.gz/sha512/17f6fbd96ed5029f360c101cedad127881e14b42498d66f717448d99ca1909057ae79169d934e08157edcc7467db4b3941bdda26a2e9f42645963eec51f27e29 +libLLVM.v18.1.7+2.aarch64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/md5/bd3b904b5f9464aaaf87c41b899c8ca5 +libLLVM.v18.1.7+2.aarch64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/sha512/fa99e8025419a18f548f658ea589771c2803480c3cb3a25cfb75e26ed0993b7b37bba204d7cba1475319a71159813b2b58a3b3327ba24d264cf80ef24263628d +libLLVM.v18.1.7+2.aarch64-linux-musl-cxx11-llvm_version+18.tar.gz/md5/b4f9038d5c3c13207111ee1a9a918cba +libLLVM.v18.1.7+2.aarch64-linux-musl-cxx11-llvm_version+18.tar.gz/sha512/e8b97bee30f597cc06d31175e12f0c2035aef0054e8abdb431f31b1e9d440d561bd9bc6637a403441aa7f3e1d2a46c600734e17e3b7ed0ae899c92df91758780 +libLLVM.v18.1.7+2.armv6l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/06d8e634b4a6914efc18b7962df52021 +libLLVM.v18.1.7+2.armv6l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/cf6aeed1eaf652e5830e34dd2ba88abc33668953281146106bbfdbc92f5f225645f00ff5b4a0eb902baf904362ab4eb32192fa50ee5b2672e8b031fe2550f9a8 +libLLVM.v18.1.7+2.armv6l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/md5/53e83804b63e6ae4d0f1c97abcbbd1c8 +libLLVM.v18.1.7+2.armv6l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/sha512/45b3ee9b105ef2ef106fa8ac7b8e902cd1d6bf3c9bfb57edeca9e14f1654714d23fb086b369a9fd3cbb828c04fee4cfe80d2b2a2bfaa852d3ac65c0d213d8c62 +libLLVM.v18.1.7+2.armv6l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/91b6cf00564053d385e30b34e5b8778e +libLLVM.v18.1.7+2.armv6l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/9111f3f02b49bf78340c9b0c5c1325a1ca09b62c83aefece1121573dcc21dce095060351f18997971e5cfbaab346cb12c75cdc0fbe8fa92aca2e8a68b5f5f577 +libLLVM.v18.1.7+2.armv6l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/md5/f6c91b71dfd73c7301a4e3de48e072de +libLLVM.v18.1.7+2.armv6l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/sha512/581d7e1e4d85aeaf082fa31555074471705e391de0771bf66665807afb5192c79c481ca30e73a25f4e2d48d4d325f0198e39bcbfaed2c9bc7477ee917667f5ce +libLLVM.v18.1.7+2.armv6l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/ce41ee46959e5e3a17b6c99293afedb7 +libLLVM.v18.1.7+2.armv6l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/73d8c5af750ea9deef822aec58d8697243ca154bc4435ac0b0ab8c90fc97750e91fa55f8de7b8283eb1ab19951cda3e3c4c60834bcf13730163e593126a8eb57 +libLLVM.v18.1.7+2.armv6l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/md5/67ed5b654852dad400aef17fb542703f +libLLVM.v18.1.7+2.armv6l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/sha512/07f70c57e27eea37f520f6f0a954b54d2506530d5eb5a74e5a8526ba8ef55a948073c49037544b602d03d0aa482704292eac943f0a83421386ccbfbf22ee8510 +libLLVM.v18.1.7+2.armv6l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/5b8bd88d49ce21e5b63af6f77782eed4 +libLLVM.v18.1.7+2.armv6l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/cef1c561ae388b2baa08e39dc195989cb795d8a2747f5f11e0dc9d9e107b9e99dbba465335376beff2e1b326512f6afc962775e0b246f3edcfadf509235cabd8 +libLLVM.v18.1.7+2.armv6l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/md5/5fbf26d20b2ce3f61edc9a9ca2eb5284 +libLLVM.v18.1.7+2.armv6l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/sha512/2c564c95d648458b9a0f0c963246cf5564c625107682f680390b6db5fde0e2b15a964fd3fd23734b5b2bb135db1fc698812d61b3f275710593f4defaee4a9c23 +libLLVM.v18.1.7+2.armv7l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/c81bc29a75acf4f806f3eb13bf890604 +libLLVM.v18.1.7+2.armv7l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/c8c922a0a4fefd549f1c2ba396a3cab9cf7738aa82e7ccf7ca29c090260e2d73ec45d6f2b07173d584f6074b10fa04052114deef6ecb6f53ea87f1924074137a +libLLVM.v18.1.7+2.armv7l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/md5/1fcb40ba1a427105b4e7d13a6c11dc78 +libLLVM.v18.1.7+2.armv7l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/sha512/392c9ee85ba7ab6697bb8979c7f443d1d25f7ac9178e96a886401cfc68d75a43ce98bf3038a7ba70a9a990f65e604d38e043472cec3badb25fbd1b38cfbb7162 +libLLVM.v18.1.7+2.armv7l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/427a19eaf69725d11bb33f48de9cb205 +libLLVM.v18.1.7+2.armv7l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/542e209b10c13d8dca867247a7414f84adb832f40051fcbdf0dcb09bc9664a77248e1b0ea1687805847dd9f5a05b86475dd76aba427c9a1bc83f8502444c60bd +libLLVM.v18.1.7+2.armv7l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/md5/ab34bfa2950014936edd13a7b5db8170 +libLLVM.v18.1.7+2.armv7l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/sha512/6376b25d0278e5c97581480fb4d54371b09a08be88f4cc39d2c7b3875f1189cef60c1be6bea5e12b0cf306cef8b394bc7d00f8b0fd95d749bd1b4eb318af7e15 +libLLVM.v18.1.7+2.armv7l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/cb6300fe87fd7cb9840f3bc44af26878 +libLLVM.v18.1.7+2.armv7l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/a7984cd90fef55559142fc05d91b0da1f37f77f25214e93ff7641b7c3958f08dc7c082611915dbfda4bbbaa392656ac8604d4f75369777dacfb78baee2f99b16 +libLLVM.v18.1.7+2.armv7l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/md5/b8a4e8ef43340e9cbdf5e4479c6a5a56 +libLLVM.v18.1.7+2.armv7l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/sha512/fc249f2b666c8a8129e05ea08c773cbeb7af6d37791f271461eedd99adcfc5082e8609ed096d8a46edd1e73505352712a41e0ddc247a371f78227aab01fbe0f3 +libLLVM.v18.1.7+2.armv7l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/5864689df3298be4b1b4df1ae0412d3a +libLLVM.v18.1.7+2.armv7l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/8f32f73e366c3a6993fa8d6b8cd1a9391611b0644cd4a77a4f7a235c037fdb75308d99b5a23ada6e4a73ed5fbd8f929a981d6bf317d79d52396220c221619303 +libLLVM.v18.1.7+2.armv7l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/md5/6bf798476c4e94716cc47a95580104ad +libLLVM.v18.1.7+2.armv7l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/sha512/9dbd27a000dd3c3dda9047d366a667c4b179cc61582525adb0f8227e8055413ce46efcbc1530305400239656e2f1016fb8833fb7f4734714078e035d388f3531 +libLLVM.v18.1.7+2.i686-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/66e2889f86ae6bc1977419e6d9be729e +libLLVM.v18.1.7+2.i686-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/d0cac798c4979b4d818d36596b173e523cba3f41ff7ab1e2111f6a75c3e819e563e207a547328f005c5a93c7f8f88c17bf43c1139b5c2690df4f1d719f82920a +libLLVM.v18.1.7+2.i686-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/0534b72d6d33c8573f79dce8a2a5a6e6 +libLLVM.v18.1.7+2.i686-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/6beaf1b45eec8b46fbf92f692f53e6df40bf48e50589aeb5ef99240a5a3ec9089ffb350dda6df24530937d613bf6d2cc4da76e92921ea00def9d2d38ac5bbeba +libLLVM.v18.1.7+2.i686-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/2cf9a1ca20472179ce4a9eb3a949457b +libLLVM.v18.1.7+2.i686-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/cebae06ccee12a14d20d3056ce0519b1e774e3c9d9200a783262fcc40aee6d7aabfb08714bf53b88e03d8b09a96d3cda248a70c16188f8c707b291642998262a +libLLVM.v18.1.7+2.i686-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/4712f6a46e0ff407ece958a7701511b9 +libLLVM.v18.1.7+2.i686-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/9a0a2dfa2076b93027f766277a6890cf94d67c131697f74945e92cf13ae64e84c09d3dd744498986fb22ad5e5465300aa9c8ae6632fcf919a0932515edfcc1e6 +libLLVM.v18.1.7+2.i686-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/md5/b944ae477232ef10d213b4c7743280fb +libLLVM.v18.1.7+2.i686-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/sha512/25ff757620baaf6fbacb375b103dc0dd9af6a23c3d3bca567c182a6357a367ca125d7b6c66927d7db23816865b6ec783157352fba08532336de467be80efcb9c +libLLVM.v18.1.7+2.i686-w64-mingw32-cxx03-llvm_version+18.tar.gz/md5/52345a44b3ac74b3cdf93852bbc63710 +libLLVM.v18.1.7+2.i686-w64-mingw32-cxx03-llvm_version+18.tar.gz/sha512/3e5b449b0f1bab302c45f9ee9f04d2cfbb01ce24e86096aa610fdf360ad65828f1b73734beb28b3d3c249ba8ef657d2663c5492940504f47c973038733b15248 +libLLVM.v18.1.7+2.i686-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/md5/36e058b96771b4cf77e29b800227fa03 +libLLVM.v18.1.7+2.i686-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/sha512/98873cb2963c4469b0f69ad1d9d9e27056aabfb46a2642dfa3507b7fe2f0b0fc41c3991a2543125291783699e39fcbcac0bd6e92fa8f0df97609a85c340fd25b +libLLVM.v18.1.7+2.i686-w64-mingw32-cxx11-llvm_version+18.tar.gz/md5/3b3823fbafabea289a769958f633dcdb +libLLVM.v18.1.7+2.i686-w64-mingw32-cxx11-llvm_version+18.tar.gz/sha512/91a9c1ad6f37cb1186ba3392935fb55d49e0f8d6afc768cf881886f9b1d8b0a2b0ecf0c81a8e32e36d32cac04c065ac852bdb95ba5ff6780c00a763583a02973 +libLLVM.v18.1.7+2.powerpc64le-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/bbf060d61b294b86f7e3dde381b00b8a +libLLVM.v18.1.7+2.powerpc64le-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/632372d41f6e400a10fae27c6cd06a5a344cfb5902cad7928cb4133f14f36f0a3373e69e73ce9baf52f518340593c3a5a16173ef59a1878e6300e9975aeaa157 +libLLVM.v18.1.7+2.powerpc64le-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/3d730b713e01cdb5a7a5a46028afd41b +libLLVM.v18.1.7+2.powerpc64le-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/052ab4fa7ac3b2c430601753ab078cdc9fd6db7f65ee0b76bb05473f4c5b99ec8919ad9d347425f1928cf619548e992c86ba97f9994218f50bca617e43d2f0d9 +libLLVM.v18.1.7+2.powerpc64le-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/bf9dcb92ba8c031ae62ed4434fd5447f +libLLVM.v18.1.7+2.powerpc64le-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/e53be14dd02a2cef8eccafb9301d29c51d652c635703529c1444947002993f6639083eb8bef13af21c9796717ce4b3129dcdcbe2751a1173d39e321db8f6e3c7 +libLLVM.v18.1.7+2.powerpc64le-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/b5cab0fc7c6643c6dd161f1e553ef1a0 +libLLVM.v18.1.7+2.powerpc64le-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/4032634449e2669479761c4323096b152f8df4948e3a97eea10f0b400fbf2a00d1edda59b74a714b62c4e204b113d8ecda78d828c3344ebe8bd750d14b3c4c7d +libLLVM.v18.1.7+2.x86_64-apple-darwin-llvm_version+18.asserts.tar.gz/md5/054e06d882173ede2886c510e8519c80 +libLLVM.v18.1.7+2.x86_64-apple-darwin-llvm_version+18.asserts.tar.gz/sha512/eb97ec25354badcac1b8a4a09fd9e04cfbb7d35493c54cff82af9ffa4c2dc5070c9232a86e900d6eb9acb03f1c572fcde8d2a865477bf6c9fbfc139763a9dd1c +libLLVM.v18.1.7+2.x86_64-apple-darwin-llvm_version+18.tar.gz/md5/f1c23200365b659f0dc07cc6d0a32c60 +libLLVM.v18.1.7+2.x86_64-apple-darwin-llvm_version+18.tar.gz/sha512/fad13fef7e7584b3f756fce9125950e788e79608cf5d0c023cb8f8a4e79001afefa8060f7866875e4861a268b3020e50305e66bf472360c1d92fce12d7a81ba9 +libLLVM.v18.1.7+2.x86_64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/69564913bae176a167d24d3291ef7af7 +libLLVM.v18.1.7+2.x86_64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/b8eeb86b66d767218e59671bdd597623238eea72319913c2ac5e116faec3f4c13739a24f3b95338ed857ec29e714dc0308e4ddbfe359332b3c27ad5235052342 +libLLVM.v18.1.7+2.x86_64-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/bc9d5637fe30f21d2231a98371e798e4 +libLLVM.v18.1.7+2.x86_64-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/4efbc2823322abe80d0134d35926767bd9cab717cde9308726a6a8891e5a707476138888c695ed399e3dddb57baf17abbc43a0a338cea2e5c0f472ab427c12e3 +libLLVM.v18.1.7+2.x86_64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/8492ff91e6dbd1a66edd8aaf0390a582 +libLLVM.v18.1.7+2.x86_64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/6443bd2fa9c5beecc2b002c26595f2cf3a8e2ea5eb49aa4c00f7252a6623fe0f8c01824941ebe5475460641285c4e56a5203056c1b93a78250b7e48fb5ac9e00 +libLLVM.v18.1.7+2.x86_64-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/6918c9978fd8b5887c66eee76950478d +libLLVM.v18.1.7+2.x86_64-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/d455a4f433bf3ea1b5100b9d45199bc785e4b6fbc7659bf06cbde6ada471134e7d4243d3a3a1f71d579126ef8371d70e59f174e124b3ff8d4842e9ee83e2dea4 +libLLVM.v18.1.7+2.x86_64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/md5/075f87d106dd95c8e9c6e7e157b5e9db +libLLVM.v18.1.7+2.x86_64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/sha512/8132379d8f44a21082c7a90f58a7dffb0c6ee725efd58a959d4023787411b080d72913bb1e89a35072f97aaf1ca512ab1d027b37eaed819e3c053d7a0cf64269 +libLLVM.v18.1.7+2.x86_64-linux-musl-cxx03-llvm_version+18.tar.gz/md5/4cfc2838a77f05883f82e50b3723dcfe +libLLVM.v18.1.7+2.x86_64-linux-musl-cxx03-llvm_version+18.tar.gz/sha512/20079c81cd6a4020b087485be1ab4928b3bd3e1a53728cc98137a35b969484278093bc75a9e51ddfd8331556577c5fb3109d74dc2eccffa93b5390e0fabff2b1 +libLLVM.v18.1.7+2.x86_64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/md5/5b8cbf00631bd4540b7335a86302a1fe +libLLVM.v18.1.7+2.x86_64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/sha512/51ba9a4b74b740905cee4baf7f4e5f3620ed81e0746f49cd352d874ebedab95277c5031123f880c9239b7dbf505b10f6531f79c8a6b0482a652b8324f4137cf5 +libLLVM.v18.1.7+2.x86_64-linux-musl-cxx11-llvm_version+18.tar.gz/md5/11010cc2d58b1a8c6a6e7bc24df0c0db +libLLVM.v18.1.7+2.x86_64-linux-musl-cxx11-llvm_version+18.tar.gz/sha512/a6bdd9a2a2fa9a572e74ced69c3ce9d1b84cde18155ec9bc7dfbaba411ee6c43d229e6fb333eff66fb63b632b485b46b7cb1657c0c49d9d9bb849fa13f0bbc7b +libLLVM.v18.1.7+2.x86_64-unknown-freebsd-llvm_version+18.asserts.tar.gz/md5/8afe26d16d9fdb0fe6c0248c51b4f053 +libLLVM.v18.1.7+2.x86_64-unknown-freebsd-llvm_version+18.asserts.tar.gz/sha512/32a92685f417c1887aef3cd8a9cadccc4de3e560ba8fc42e8db721f273a3451927b24dc4a2c2e83446e32a84d47f714fc3c22ce71989f2e97c5ca23a1783b8d6 +libLLVM.v18.1.7+2.x86_64-unknown-freebsd-llvm_version+18.tar.gz/md5/59d8d911907127ff56f5eafcd8663300 +libLLVM.v18.1.7+2.x86_64-unknown-freebsd-llvm_version+18.tar.gz/sha512/9b0bf6f9d8d32ccbec349c249b79fd0fa3b4949c04b69c9d408f19dfa3b4f00e5cfa51b798234721f72f2793161d6af6491856e10e6a507976b0da6ed7a8065b +libLLVM.v18.1.7+2.x86_64-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/md5/b0d9a7eca92d40ecbfa47461d52659e2 +libLLVM.v18.1.7+2.x86_64-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/sha512/dc4a91e164d88ff51b4a642b556d5767156f28d1efafa533f5d7c619e05535e2000afb2ea47469a90f5a19f970e8f0522f35d59ec250e2f9b42ce22fadb9ffd3 +libLLVM.v18.1.7+2.x86_64-w64-mingw32-cxx03-llvm_version+18.tar.gz/md5/92a60309ad33391415c6703edbbd5423 +libLLVM.v18.1.7+2.x86_64-w64-mingw32-cxx03-llvm_version+18.tar.gz/sha512/2fe90ac804d94bcf0d4058a8b8f0c274e405ffee7df0175f5e7ccd5014b29a813af48152870e1af0a79df8d3eec3118c233bc4f5b3f8439fd9792931140ee944 +libLLVM.v18.1.7+2.x86_64-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/md5/0964df17cb98d2d869a33468477f9901 +libLLVM.v18.1.7+2.x86_64-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/sha512/2c062acd62175d32dda773e9116608ced814a64ab06ea73f89958437178e2603b268638e88162fb81c22e5947cf4cc925b1af10c6f9320be22c92b279b278992 +libLLVM.v18.1.7+2.x86_64-w64-mingw32-cxx11-llvm_version+18.tar.gz/md5/7dfb8e61e972c66f1d754cb979bc0309 +libLLVM.v18.1.7+2.x86_64-w64-mingw32-cxx11-llvm_version+18.tar.gz/sha512/d462b6fe7aea75f6fee6c5c2f24576569b5deac8027fb88240e16c55a54d68b7dcb06b3ec4ab514616fb88549fc2f10fb1d587a641d6f29fa66273904bb9cfd8 +llvm-julia-18.1.7-2.tar.gz/md5/5c0ae4abc4ce31a86d5d6d4ecabc2683 +llvm-julia-18.1.7-2.tar.gz/sha512/b4d1dde929a8670eec1a9b25abe23fbc926a922e61b60ed99b52b440cd07cb026e7f746878292db4cd0cb422d9b87ecc4ee4b2b141f8e9411855d18da51facb9 llvmunwind-12.0.1.tar.xz/md5/4ec327cee517fdb1f6a20e83748e2c7b llvmunwind-12.0.1.tar.xz/sha512/847b6ba03010a43f4fdbfdc49bf16d18fd18474d01584712e651b11191814bf7c1cf53475021d9ee447ed78413202b4ed97973d7bdd851d3e49f8d06f55a7af4 diff --git a/deps/checksums/openblas b/deps/checksums/openblas index ad6b38dc075fa..51317261c82a0 100644 --- a/deps/checksums/openblas +++ b/deps/checksums/openblas @@ -1,94 +1,94 @@ -OpenBLAS.v0.3.27+1.aarch64-apple-darwin-libgfortran5.tar.gz/md5/7bb5c7a169ec7660ec38fe73c74a89d7 -OpenBLAS.v0.3.27+1.aarch64-apple-darwin-libgfortran5.tar.gz/sha512/97266fa0d786bac50f37d82e66da645dfa1b811975045d4aaad1f49361caf7945c06203cb728bf92e9071ec805dff2c75f2b45b346ae4f9cfe289d8f2215e68b -OpenBLAS.v0.3.27+1.aarch64-linux-gnu-libgfortran3.tar.gz/md5/ea42c557a49aa58172ea0e0f0f93c628 -OpenBLAS.v0.3.27+1.aarch64-linux-gnu-libgfortran3.tar.gz/sha512/baade18c9d8d91f3fb32e44609277a7a6cd827a6c9554e5b21f88d492a0c34e93d29041f691f6b0cd03ab609d5470b1a06e95121781e9622cce301812d6613de -OpenBLAS.v0.3.27+1.aarch64-linux-gnu-libgfortran4.tar.gz/md5/85a9cbbbf9fff65927a9ff96f17d0792 -OpenBLAS.v0.3.27+1.aarch64-linux-gnu-libgfortran4.tar.gz/sha512/7a0024c509a50c87c9318d209465e0d57fc2e0a8401740666f09d236678eb9d5a1b2fbbfd12c0c409006607a408f03f11c1465841417533010a7843c4af654c1 -OpenBLAS.v0.3.27+1.aarch64-linux-gnu-libgfortran5.tar.gz/md5/4e3c6a68a61b9749ebb55b20728bf0f1 -OpenBLAS.v0.3.27+1.aarch64-linux-gnu-libgfortran5.tar.gz/sha512/dbf9fc5465f60a35849c391069c0a9d6d6fc8685b734d00088e297cf7a6c92fbed67f4264f2b2c164d3c6694d9c8f64b750faa248aa1fd44867d18a94211dc87 -OpenBLAS.v0.3.27+1.aarch64-linux-musl-libgfortran3.tar.gz/md5/c25b607a4df84f9aeb112f24520cabb3 -OpenBLAS.v0.3.27+1.aarch64-linux-musl-libgfortran3.tar.gz/sha512/a99fa75a3cfea19c84a4d455585e53f124e956dd5d4ee7ce0c38c0922b0bebb8b2c996079c3bc63e95444b531ddf9d1f003a22d7f6b55cf99db2334bb1c618ae -OpenBLAS.v0.3.27+1.aarch64-linux-musl-libgfortran4.tar.gz/md5/3473d20c26f6ad50f3a0b635415858a5 -OpenBLAS.v0.3.27+1.aarch64-linux-musl-libgfortran4.tar.gz/sha512/6e9100e0fcbe1b91c5a4461118739af9d4eca7edd7b8e6ee07a2052c0aaad0ea84c048f0e507ff88da81f47b10c102faf9fe735d13ae1cd35f44396d9a51a864 -OpenBLAS.v0.3.27+1.aarch64-linux-musl-libgfortran5.tar.gz/md5/9ad49254a2827987e622a58a1b8c7b98 -OpenBLAS.v0.3.27+1.aarch64-linux-musl-libgfortran5.tar.gz/sha512/f8a3b9aa52920ce76f5d9550407aeefed5e2596d05b9f8f0643e1da221cf533a09de7a0454a04a2d59a3a2a2fb899a538a5e03b133746415a81415ff926826ba -OpenBLAS.v0.3.27+1.armv6l-linux-gnueabihf-libgfortran3.tar.gz/md5/c130634237846672f3a672f1d0e346d9 -OpenBLAS.v0.3.27+1.armv6l-linux-gnueabihf-libgfortran3.tar.gz/sha512/c174d00870ce3944c553122606cba7b78312342a02dc4833a91ae105f05d85d06e665e86a79452bdb7d2b31c18936582d79427ec3976048cf09497011d8c77c8 -OpenBLAS.v0.3.27+1.armv6l-linux-gnueabihf-libgfortran4.tar.gz/md5/07c58a9399552e3b8362d9c1dd155693 -OpenBLAS.v0.3.27+1.armv6l-linux-gnueabihf-libgfortran4.tar.gz/sha512/98570a4dae80f9b4366c08994911efc87bf6967e63e20b486240a3b2d7637fabbfcca3fe8340ae4d9bae7702be400f5976fc5aa0020f984157b097b02e08d23c -OpenBLAS.v0.3.27+1.armv6l-linux-gnueabihf-libgfortran5.tar.gz/md5/25a9af724bb8a5ca42be6277a726583e -OpenBLAS.v0.3.27+1.armv6l-linux-gnueabihf-libgfortran5.tar.gz/sha512/7afbc7453d1f22171523476e90882f67611374b03a3481bdb588722bc4816d081304b811a0dd452288ca972bea95bd2d2286644bda309dbe25fe721321298e85 -OpenBLAS.v0.3.27+1.armv6l-linux-musleabihf-libgfortran3.tar.gz/md5/2f9494f7600729bfa00a0db96bd9349d -OpenBLAS.v0.3.27+1.armv6l-linux-musleabihf-libgfortran3.tar.gz/sha512/eae895a7ef4d9922bf9f6c454f56b2881fd5549e6c6a825e0e4d5b84defe9a97719a9f1e62f996dd545afdf372c1ab18bbee0a6cce8474d9adb2522b16678d35 -OpenBLAS.v0.3.27+1.armv6l-linux-musleabihf-libgfortran4.tar.gz/md5/8f30a26bd56ced5d6edc88b1fae57beb -OpenBLAS.v0.3.27+1.armv6l-linux-musleabihf-libgfortran4.tar.gz/sha512/ad849216c9655dc160a0cd756904442a80d693121e60a2b33876ac347c79fe6e3e602faad0c64a45599f5a5e203c3d9e8316c6b20c41d81e666b7650dccfaa5c -OpenBLAS.v0.3.27+1.armv6l-linux-musleabihf-libgfortran5.tar.gz/md5/272facb48c295ccfea2a291869e1817e -OpenBLAS.v0.3.27+1.armv6l-linux-musleabihf-libgfortran5.tar.gz/sha512/7fd5c23046fa548f0bed6e7ce4f6fa809e56909b5595d2a4f348189ee99f234dc84989219ee63cdc004ce303b50fee2aa1fcb93589ff116a2191f8ef520d24be -OpenBLAS.v0.3.27+1.armv7l-linux-gnueabihf-libgfortran3.tar.gz/md5/c130634237846672f3a672f1d0e346d9 -OpenBLAS.v0.3.27+1.armv7l-linux-gnueabihf-libgfortran3.tar.gz/sha512/c174d00870ce3944c553122606cba7b78312342a02dc4833a91ae105f05d85d06e665e86a79452bdb7d2b31c18936582d79427ec3976048cf09497011d8c77c8 -OpenBLAS.v0.3.27+1.armv7l-linux-gnueabihf-libgfortran4.tar.gz/md5/07c58a9399552e3b8362d9c1dd155693 -OpenBLAS.v0.3.27+1.armv7l-linux-gnueabihf-libgfortran4.tar.gz/sha512/98570a4dae80f9b4366c08994911efc87bf6967e63e20b486240a3b2d7637fabbfcca3fe8340ae4d9bae7702be400f5976fc5aa0020f984157b097b02e08d23c -OpenBLAS.v0.3.27+1.armv7l-linux-gnueabihf-libgfortran5.tar.gz/md5/25a9af724bb8a5ca42be6277a726583e -OpenBLAS.v0.3.27+1.armv7l-linux-gnueabihf-libgfortran5.tar.gz/sha512/7afbc7453d1f22171523476e90882f67611374b03a3481bdb588722bc4816d081304b811a0dd452288ca972bea95bd2d2286644bda309dbe25fe721321298e85 -OpenBLAS.v0.3.27+1.armv7l-linux-musleabihf-libgfortran3.tar.gz/md5/2f9494f7600729bfa00a0db96bd9349d -OpenBLAS.v0.3.27+1.armv7l-linux-musleabihf-libgfortran3.tar.gz/sha512/eae895a7ef4d9922bf9f6c454f56b2881fd5549e6c6a825e0e4d5b84defe9a97719a9f1e62f996dd545afdf372c1ab18bbee0a6cce8474d9adb2522b16678d35 -OpenBLAS.v0.3.27+1.armv7l-linux-musleabihf-libgfortran4.tar.gz/md5/8f30a26bd56ced5d6edc88b1fae57beb -OpenBLAS.v0.3.27+1.armv7l-linux-musleabihf-libgfortran4.tar.gz/sha512/ad849216c9655dc160a0cd756904442a80d693121e60a2b33876ac347c79fe6e3e602faad0c64a45599f5a5e203c3d9e8316c6b20c41d81e666b7650dccfaa5c -OpenBLAS.v0.3.27+1.armv7l-linux-musleabihf-libgfortran5.tar.gz/md5/272facb48c295ccfea2a291869e1817e -OpenBLAS.v0.3.27+1.armv7l-linux-musleabihf-libgfortran5.tar.gz/sha512/7fd5c23046fa548f0bed6e7ce4f6fa809e56909b5595d2a4f348189ee99f234dc84989219ee63cdc004ce303b50fee2aa1fcb93589ff116a2191f8ef520d24be -OpenBLAS.v0.3.27+1.i686-linux-gnu-libgfortran3.tar.gz/md5/14cee2ac2cff0d9d8b614278e3f7a4ed -OpenBLAS.v0.3.27+1.i686-linux-gnu-libgfortran3.tar.gz/sha512/d81aa1c8ff70d8d24d2cf88adc568dbf6a77f191332aa0298fbc0faad1fda855c9a6c278d0556003cca315ef75e47cf7caa6963b4e16f4d883ba7c1b13a298bb -OpenBLAS.v0.3.27+1.i686-linux-gnu-libgfortran4.tar.gz/md5/559f96fb8a2a03df6689200173f2c1df -OpenBLAS.v0.3.27+1.i686-linux-gnu-libgfortran4.tar.gz/sha512/cc1e987b2ad7d47b474d39b0f93ee6f6e46a4e5d0760cea9e31a0d3c5336e6cfc88401122ab278c0b745c9e60b290f9c05edf39bef9e7e97c70f33dc7afac341 -OpenBLAS.v0.3.27+1.i686-linux-gnu-libgfortran5.tar.gz/md5/c572b06af06609e5e84dc8aee61babc1 -OpenBLAS.v0.3.27+1.i686-linux-gnu-libgfortran5.tar.gz/sha512/d799e280600970697701098f76e79d0bb72bf55cbe8d6c131bd26f6a67bdcb5ed307b26eae89bc6b7cc6b6eb25d2622f952b315f7850b7f231148f14cc09b769 -OpenBLAS.v0.3.27+1.i686-linux-musl-libgfortran3.tar.gz/md5/4aa9f25b39088f79ea13aab1097c0c1f -OpenBLAS.v0.3.27+1.i686-linux-musl-libgfortran3.tar.gz/sha512/126876d9de1c67302dc1b9b71a96fd2f5eb45745ebbcea6d4b7d4bdfac93088ef6b89e75a2bfcd83f1b32dc798b7ef824bb225e24e88e6443571d0576939bb05 -OpenBLAS.v0.3.27+1.i686-linux-musl-libgfortran4.tar.gz/md5/4ffd9c16cd3c6535457dd654f95c62e6 -OpenBLAS.v0.3.27+1.i686-linux-musl-libgfortran4.tar.gz/sha512/cc7fbe4949b5b51e5f1f5fdae537bbcc68ef4a59a02c290df2f6723bdeb52d98e699e4b23a879372d56279196295d8c938ba2221fe3a73cd1ef953059cdf694f -OpenBLAS.v0.3.27+1.i686-linux-musl-libgfortran5.tar.gz/md5/7d6855b9a879259216c243dcfc75a2cc -OpenBLAS.v0.3.27+1.i686-linux-musl-libgfortran5.tar.gz/sha512/221d1ba0250802ae88daac384fd1b2c911c49f8e141efbf3c2668260f4018c5e5f1e21c459a1595652ca48ebc446fe43e54fbf732b47d68f20ecb1e280862570 -OpenBLAS.v0.3.27+1.i686-w64-mingw32-libgfortran3.tar.gz/md5/646fdfccf16f12f23441723e13c12f58 -OpenBLAS.v0.3.27+1.i686-w64-mingw32-libgfortran3.tar.gz/sha512/2692aae16acba199584da71275eb609071d6f7a6d644239f9b6307fe12fc875d6267b11d387b2cace1d5866bf50ab0db619510d02acd3c90696bfb0dfe958037 -OpenBLAS.v0.3.27+1.i686-w64-mingw32-libgfortran4.tar.gz/md5/257e35006373e43fedb211c56b73315a -OpenBLAS.v0.3.27+1.i686-w64-mingw32-libgfortran4.tar.gz/sha512/e4d8049a6e30763dbacba7646805bb72abad021f8810fb084a287d389137e30b96f12f04ad625c5ef322d127f7b603f388fee18a516e101761391d405ec58d2e -OpenBLAS.v0.3.27+1.i686-w64-mingw32-libgfortran5.tar.gz/md5/68245d8b061c60f97f48fd4fde4492dd -OpenBLAS.v0.3.27+1.i686-w64-mingw32-libgfortran5.tar.gz/sha512/511f5fcb538067c04742ad578d2584ebb3cc54bd7c43b84b14d3597bcb84d303a729a48c79018afa119ef12e084bed5ce6fe3591774a1cd6a5b6bbe5df4a8753 -OpenBLAS.v0.3.27+1.powerpc64le-linux-gnu-libgfortran3.tar.gz/md5/883728fe99e27d1f066032e1465880b2 -OpenBLAS.v0.3.27+1.powerpc64le-linux-gnu-libgfortran3.tar.gz/sha512/3363ad953d1d7b5ba233b5d6ff65411e51189adcc6e7a9b68e45388132b38701eba53745f826f896820a98bc5015a8787ab1257f1a25c0a55f0437707c451d20 -OpenBLAS.v0.3.27+1.powerpc64le-linux-gnu-libgfortran4.tar.gz/md5/672fb00c47939bfc1893c7bf630b6904 -OpenBLAS.v0.3.27+1.powerpc64le-linux-gnu-libgfortran4.tar.gz/sha512/e1beb8be0b58402df60b14a81d4fefe13cb0a30450717c80f2670b3a7947a89574848e858f90e0efd5474c47cdb86ce5623645988f05f105df206abd888c2f58 -OpenBLAS.v0.3.27+1.powerpc64le-linux-gnu-libgfortran5.tar.gz/md5/32eeeeeb57ed38bb4123ea793faf6685 -OpenBLAS.v0.3.27+1.powerpc64le-linux-gnu-libgfortran5.tar.gz/sha512/bc505de8d8378e5c0fd6b3092b7093ecae0cacd9d5f6fa94e6e01ead03ffd7abad31c8d75fa84cf6da4f4fd33dde33df968595ecdc818f5b891b82db1be2d1a1 -OpenBLAS.v0.3.27+1.x86_64-apple-darwin-libgfortran3.tar.gz/md5/e49f4562399b5d45d987e9820774f7c8 -OpenBLAS.v0.3.27+1.x86_64-apple-darwin-libgfortran3.tar.gz/sha512/0e5ade0c2112f01b3bde14ddb0fe500085d75fc86117d54bc66cc2da30f7251233387a90daca6203ebe457bc68e8bf3cff62c011b424a971ff9f7932974eaba4 -OpenBLAS.v0.3.27+1.x86_64-apple-darwin-libgfortran4.tar.gz/md5/26c9067086aa013de9c3b4001cd3f78a -OpenBLAS.v0.3.27+1.x86_64-apple-darwin-libgfortran4.tar.gz/sha512/e641bc045b96cb011183e26541730b46b8dfb401ef1223f10f19450de206d9971f3181d37c7687477d782238e580bbba4fddbcb2094a45761b55dcc93a9cacd4 -OpenBLAS.v0.3.27+1.x86_64-apple-darwin-libgfortran5.tar.gz/md5/a2cf4ac08dc296f6aaf109e8d1fff491 -OpenBLAS.v0.3.27+1.x86_64-apple-darwin-libgfortran5.tar.gz/sha512/2210bc1dfa32b0b9b86ec84943b6673bc540a0822652274ececa0f394ed406d9f23f02909f2b8f97dd2a2bc114df2d0e9a6d868d29bc2d08a3da7176743a6d10 -OpenBLAS.v0.3.27+1.x86_64-linux-gnu-libgfortran3.tar.gz/md5/1b501f18b00d1e051b4af955da81b3c9 -OpenBLAS.v0.3.27+1.x86_64-linux-gnu-libgfortran3.tar.gz/sha512/1b5615dc63efd0166b206bbdc90801d0c623f93f537c320bac1af8bf41f9e3ae8ec33eb6b43a7bd9dc2d9ba526bc7bb200ff828f33ef36da920f9290fa4ff252 -OpenBLAS.v0.3.27+1.x86_64-linux-gnu-libgfortran4.tar.gz/md5/079cebb72efd39454275a8199fc78c17 -OpenBLAS.v0.3.27+1.x86_64-linux-gnu-libgfortran4.tar.gz/sha512/94bdd5db2546381e3cd15bb60b382c11d8ba879f8b88771a15d0d7cbf5a399f46aec60fc01e07258614ec039bf9bf73cbeffc9d2f29b03c9885e63704f0d2ab0 -OpenBLAS.v0.3.27+1.x86_64-linux-gnu-libgfortran5.tar.gz/md5/cef6229311f1616c0db95cef84725cd4 -OpenBLAS.v0.3.27+1.x86_64-linux-gnu-libgfortran5.tar.gz/sha512/297eda815134d5de59d1614b39f06a512f4ef544dc5abaffa015075a8bcba1506aa4825109213e54e94401cbf16d4292a1ec2b9b71b278cc8536379d80d96e46 -OpenBLAS.v0.3.27+1.x86_64-linux-musl-libgfortran3.tar.gz/md5/b410edbbc651fd9f6589fda153b410da -OpenBLAS.v0.3.27+1.x86_64-linux-musl-libgfortran3.tar.gz/sha512/718c22a940d998dcd8c754994f5a7d9bd3e3131d51beb1d8071ca0005e5c562bb2368924b0c4951839df0bc85a272962f87891b366a1bce1f735cc2b3495b834 -OpenBLAS.v0.3.27+1.x86_64-linux-musl-libgfortran4.tar.gz/md5/af8f2dc642041d5e4eff98d6b20e7596 -OpenBLAS.v0.3.27+1.x86_64-linux-musl-libgfortran4.tar.gz/sha512/48b88f703cc0e35d8f3b3bf7f395481a3225f5c3d1a4277a7b477815feab71df5c6b662313f4762bc8002f43c0f1bece0f383bc3920c09d383303b3927925ddf -OpenBLAS.v0.3.27+1.x86_64-linux-musl-libgfortran5.tar.gz/md5/eba3e9322d39993d81d78486306b301f -OpenBLAS.v0.3.27+1.x86_64-linux-musl-libgfortran5.tar.gz/sha512/dc11716e4f7a53a396b8b8cd3e506bd66272e9e8c5533199dc972c91fed0cea5067ec8e14abf67da2b53af7f3189eafc5c188657d617eea3f55ed248d7ed38e4 -OpenBLAS.v0.3.27+1.x86_64-unknown-freebsd-libgfortran3.tar.gz/md5/03f45c7c0276f58719235e5da3bcdc85 -OpenBLAS.v0.3.27+1.x86_64-unknown-freebsd-libgfortran3.tar.gz/sha512/836fbbdae1065393de8ad1410301afbecfb0bf60256322b754e17aa5b4edb20e409eeca2f66f9a2b9ffb5872479cd3cab9b721bd2fc9c3544f5e90e78c7e59c7 -OpenBLAS.v0.3.27+1.x86_64-unknown-freebsd-libgfortran4.tar.gz/md5/dc6bc577a3ccd78364e9fcb98fec03dd -OpenBLAS.v0.3.27+1.x86_64-unknown-freebsd-libgfortran4.tar.gz/sha512/2c52880b287b0c4f48ed3539e4e0b24b6a05b46d47d7586eea7ca06ebc19c7f0d018fdd24e8da94249fa3b7dc54b85b27ebc530fc5cefb2d9b5457e00dee3529 -OpenBLAS.v0.3.27+1.x86_64-unknown-freebsd-libgfortran5.tar.gz/md5/30a6a329d4d37dea7199dfcf264a2641 -OpenBLAS.v0.3.27+1.x86_64-unknown-freebsd-libgfortran5.tar.gz/sha512/53be21e7a94033cd44b8e2d375b38606446800344698e4f365527d807f736b7b2b9a897138b5de5bd62ba9da104cd6f86bf59caebc18299c0abd98899c527988 -OpenBLAS.v0.3.27+1.x86_64-w64-mingw32-libgfortran3.tar.gz/md5/290a8fc0d1580aeed8cb7b793ff991bf -OpenBLAS.v0.3.27+1.x86_64-w64-mingw32-libgfortran3.tar.gz/sha512/e30e4f666255982c1adbf73020bf88e2d499d2d26216a16c34b4a6b7ed0dc5b7d5374a978a7d0ef5735a82394b4ef06bd82491e2ddf7ec5775953b9183e9f601 -OpenBLAS.v0.3.27+1.x86_64-w64-mingw32-libgfortran4.tar.gz/md5/1b46471021b6914fc60401e3e1ffe78b -OpenBLAS.v0.3.27+1.x86_64-w64-mingw32-libgfortran4.tar.gz/sha512/509d5138d8cd9621937f840b7f73949facec2f047676069403d3d7c482ea183766dc84536d9c2a291b18a2b89902e6f714665fa0b7a920727635530a3aa4aa17 -OpenBLAS.v0.3.27+1.x86_64-w64-mingw32-libgfortran5.tar.gz/md5/ae28948c5d496a3d0bba649c72822b2b -OpenBLAS.v0.3.27+1.x86_64-w64-mingw32-libgfortran5.tar.gz/sha512/8d66a65040e973947a8a7d4f4b1d47d63a77b75c0d5e04843de9188256aeec5a1c7e0d59bf5e1d5c262c4f1a4ff2aa36599840337e9d828fb77724c38c1fff4e -openblas-6c77e5e314474773a7749357b153caba4ec3817d.tar.gz/md5/4971eeb7adadee085d7c991db416fe7a -openblas-6c77e5e314474773a7749357b153caba4ec3817d.tar.gz/sha512/7b85c9fb7be54407ba627d77897f40de4395d6d307230aa7df83cf8e0a41f545e4af4ae0576abb40cc9e0c385e1c6a488100dff292ea307439a89587c07ba66f +OpenBLAS.v0.3.28+0.aarch64-apple-darwin-libgfortran5.tar.gz/md5/e3edc449afa805b3744eb153460b681f +OpenBLAS.v0.3.28+0.aarch64-apple-darwin-libgfortran5.tar.gz/sha512/4f619ae720bc2a55c6d7d53b78bf0a15f66c5b3474c968b367f41d71c759b39028817e3e7ba3cebc4ee06f2176578a5a1bd2be7cf2f1461a396c418292fcf782 +OpenBLAS.v0.3.28+0.aarch64-linux-gnu-libgfortran3.tar.gz/md5/e01dcbdbfd2c8f15d78efb0aa5673944 +OpenBLAS.v0.3.28+0.aarch64-linux-gnu-libgfortran3.tar.gz/sha512/33dee7c48f981b218792e150aea506989b7bbacfd540ebd1fefb150af3c33eae62cd523c329ef8f37c0b56643d480e105ed82e46ec5b3f683e006d05dda717ee +OpenBLAS.v0.3.28+0.aarch64-linux-gnu-libgfortran4.tar.gz/md5/43662cb933b2aab820bd210edd4e994a +OpenBLAS.v0.3.28+0.aarch64-linux-gnu-libgfortran4.tar.gz/sha512/520abb2521a4b9ae71c86dafc7de4155d51df09ff119a3b1d25a9bac3fb73aceaf38b7805888d4858b96e73c0d1cf80d8953b9db954df4d0e6c164894d07d715 +OpenBLAS.v0.3.28+0.aarch64-linux-gnu-libgfortran5.tar.gz/md5/5c693f190d26194353c1e096b40568bc +OpenBLAS.v0.3.28+0.aarch64-linux-gnu-libgfortran5.tar.gz/sha512/3c3e11ba038e59002d23e885e22129dda13453469dad79f39f9cddceadbf1d39e61487894f5112b2fcb5265cd98075103d99eff2a83f79407aafa545b03e9f9c +OpenBLAS.v0.3.28+0.aarch64-linux-musl-libgfortran3.tar.gz/md5/2892710a8545b4573014024222bb8dff +OpenBLAS.v0.3.28+0.aarch64-linux-musl-libgfortran3.tar.gz/sha512/6a628c9f7eab2a34198028846a6aec7bb13af4425e1b73ba5b58d326c1eb0741b5dc08fff3db565c92cbc0e2718b62fa6dedac5fa0bdb2f35561663f36f4dfbe +OpenBLAS.v0.3.28+0.aarch64-linux-musl-libgfortran4.tar.gz/md5/fbec5f47685d4bb36956cd4aee34f1e5 +OpenBLAS.v0.3.28+0.aarch64-linux-musl-libgfortran4.tar.gz/sha512/ac69a9ed17900de79c6da0ff08a97f3397860de92ce1888f77c8c8fada08fab15fff1b19868c95865ad4a387701c2ffe74e695d6949d8ba02534f91aca2a5ca3 +OpenBLAS.v0.3.28+0.aarch64-linux-musl-libgfortran5.tar.gz/md5/6a0a1a1cad6452ac687e24147128f027 +OpenBLAS.v0.3.28+0.aarch64-linux-musl-libgfortran5.tar.gz/sha512/0ea2b7f829b4e406276911db743706b17d7902899d4492e18b9676fed9b27d976d586e38505c52932e27f194c9806d6cb53182cb128baab41898605af7c346b5 +OpenBLAS.v0.3.28+0.armv6l-linux-gnueabihf-libgfortran3.tar.gz/md5/677baf1c9142f1db12c89ef98a082d03 +OpenBLAS.v0.3.28+0.armv6l-linux-gnueabihf-libgfortran3.tar.gz/sha512/0a182dba6512dd50193d7625091487bb45f61ec5edbb8adffdeb68fa43744d8c9aa1233ac709249b09fed59e63b6532bf40386dfe884c26605551a6974ed0cc8 +OpenBLAS.v0.3.28+0.armv6l-linux-gnueabihf-libgfortran4.tar.gz/md5/d6b08be3200bef4a045be99246a3f294 +OpenBLAS.v0.3.28+0.armv6l-linux-gnueabihf-libgfortran4.tar.gz/sha512/467d6d12cd56237e6128de4041dbffa3428f208e313f20975c0665abf42a3c39d6b527676573897d6b6801306a9a241da17f4231ce79f0081fb433733d3cb6b4 +OpenBLAS.v0.3.28+0.armv6l-linux-gnueabihf-libgfortran5.tar.gz/md5/8645788a731c86f26f40eaf6f65bf74c +OpenBLAS.v0.3.28+0.armv6l-linux-gnueabihf-libgfortran5.tar.gz/sha512/19ea4ffdef48ef1af6bdd68ce39986814b1732d65bcaee673cd3c0dcb5572faef53962c4ac18e0d1800eb9745324b3145f98c136606ff71d96778e85d4d6bf72 +OpenBLAS.v0.3.28+0.armv6l-linux-musleabihf-libgfortran3.tar.gz/md5/a40dc134a8a5e31bea637bc0a6ee45b6 +OpenBLAS.v0.3.28+0.armv6l-linux-musleabihf-libgfortran3.tar.gz/sha512/3d4a1a67753f41bde880ae0b1d19ad7998ae7646530d3e469829e7ea859a394dde73e20239b80e8c61b58974c266d0960cbe256dea4103b04dd4ec52318f02c0 +OpenBLAS.v0.3.28+0.armv6l-linux-musleabihf-libgfortran4.tar.gz/md5/0ff472d7bf455b8b3b50daa91241f288 +OpenBLAS.v0.3.28+0.armv6l-linux-musleabihf-libgfortran4.tar.gz/sha512/c0b306bf1ba71baebbe191d7f105287aa19fccd61ae2bc48c9b9ffd92140d4f02d3a78e0632e83924fb02c93826455493c8f5767d71b7e505a1066bd67b95dff +OpenBLAS.v0.3.28+0.armv6l-linux-musleabihf-libgfortran5.tar.gz/md5/26a05928260315bc2088842d2fa75347 +OpenBLAS.v0.3.28+0.armv6l-linux-musleabihf-libgfortran5.tar.gz/sha512/dd5ceb6b7fd028df3c4eac732857c537e81c6c8bb7662c6075e432acd51eb6421556b3453e37483481499b2557d34fcec22fda9192cd54b6c7c7205dd40ed387 +OpenBLAS.v0.3.28+0.armv7l-linux-gnueabihf-libgfortran3.tar.gz/md5/677baf1c9142f1db12c89ef98a082d03 +OpenBLAS.v0.3.28+0.armv7l-linux-gnueabihf-libgfortran3.tar.gz/sha512/0a182dba6512dd50193d7625091487bb45f61ec5edbb8adffdeb68fa43744d8c9aa1233ac709249b09fed59e63b6532bf40386dfe884c26605551a6974ed0cc8 +OpenBLAS.v0.3.28+0.armv7l-linux-gnueabihf-libgfortran4.tar.gz/md5/d6b08be3200bef4a045be99246a3f294 +OpenBLAS.v0.3.28+0.armv7l-linux-gnueabihf-libgfortran4.tar.gz/sha512/467d6d12cd56237e6128de4041dbffa3428f208e313f20975c0665abf42a3c39d6b527676573897d6b6801306a9a241da17f4231ce79f0081fb433733d3cb6b4 +OpenBLAS.v0.3.28+0.armv7l-linux-gnueabihf-libgfortran5.tar.gz/md5/8645788a731c86f26f40eaf6f65bf74c +OpenBLAS.v0.3.28+0.armv7l-linux-gnueabihf-libgfortran5.tar.gz/sha512/19ea4ffdef48ef1af6bdd68ce39986814b1732d65bcaee673cd3c0dcb5572faef53962c4ac18e0d1800eb9745324b3145f98c136606ff71d96778e85d4d6bf72 +OpenBLAS.v0.3.28+0.armv7l-linux-musleabihf-libgfortran3.tar.gz/md5/a40dc134a8a5e31bea637bc0a6ee45b6 +OpenBLAS.v0.3.28+0.armv7l-linux-musleabihf-libgfortran3.tar.gz/sha512/3d4a1a67753f41bde880ae0b1d19ad7998ae7646530d3e469829e7ea859a394dde73e20239b80e8c61b58974c266d0960cbe256dea4103b04dd4ec52318f02c0 +OpenBLAS.v0.3.28+0.armv7l-linux-musleabihf-libgfortran4.tar.gz/md5/0ff472d7bf455b8b3b50daa91241f288 +OpenBLAS.v0.3.28+0.armv7l-linux-musleabihf-libgfortran4.tar.gz/sha512/c0b306bf1ba71baebbe191d7f105287aa19fccd61ae2bc48c9b9ffd92140d4f02d3a78e0632e83924fb02c93826455493c8f5767d71b7e505a1066bd67b95dff +OpenBLAS.v0.3.28+0.armv7l-linux-musleabihf-libgfortran5.tar.gz/md5/26a05928260315bc2088842d2fa75347 +OpenBLAS.v0.3.28+0.armv7l-linux-musleabihf-libgfortran5.tar.gz/sha512/dd5ceb6b7fd028df3c4eac732857c537e81c6c8bb7662c6075e432acd51eb6421556b3453e37483481499b2557d34fcec22fda9192cd54b6c7c7205dd40ed387 +OpenBLAS.v0.3.28+0.i686-linux-gnu-libgfortran3.tar.gz/md5/36f76f7588ad5bc48c2f68daee49da57 +OpenBLAS.v0.3.28+0.i686-linux-gnu-libgfortran3.tar.gz/sha512/2184cac67657fb58afc42fff46069084ffbcbc67938e7e74e9e5a926cc83733c702cacf16ca320381f5bb1f219cbea764ae8cdb9c445f7224ac0cd0beab822ff +OpenBLAS.v0.3.28+0.i686-linux-gnu-libgfortran4.tar.gz/md5/ef8501cc6babf8be3b8b649da2a7c692 +OpenBLAS.v0.3.28+0.i686-linux-gnu-libgfortran4.tar.gz/sha512/98543cfd34a185644cebc33cd82ebfb663c92f1fa8349121e6d34f86b1d10f4f37688b84b22182f9e29daa74664a469ddc67408827e8bc7fddb1a7311d918532 +OpenBLAS.v0.3.28+0.i686-linux-gnu-libgfortran5.tar.gz/md5/598c07efb122e75e6e99ba7fc0c4fb4b +OpenBLAS.v0.3.28+0.i686-linux-gnu-libgfortran5.tar.gz/sha512/b7caa20a36d6806895f3efb02830017c3ca8037c5af3a29df00f9fe34945324c34181a945b1dbe8a8ca43c7f792667d7640c23b5c2fa4fd93564f1da78561190 +OpenBLAS.v0.3.28+0.i686-linux-musl-libgfortran3.tar.gz/md5/e7667d215442ac0db83969d41a678774 +OpenBLAS.v0.3.28+0.i686-linux-musl-libgfortran3.tar.gz/sha512/3b22dd658b5948d6867b3e57fe53976eef59339d2714709746098b96f13766d86e918a139929aa60672be91c50c7f739c5c0db372f07a71ae2447588db3685e4 +OpenBLAS.v0.3.28+0.i686-linux-musl-libgfortran4.tar.gz/md5/91d95572ce67a21d107b9fbcd3aba11d +OpenBLAS.v0.3.28+0.i686-linux-musl-libgfortran4.tar.gz/sha512/7727d24fec0a333a943de3f9d6dd5c698e4f3b9099fd838b8b5652f6216f7b9fe4a2d8f014a4f0b3b7ad7fe05b81a9079e570454d456f0462e7d04f66e264ecb +OpenBLAS.v0.3.28+0.i686-linux-musl-libgfortran5.tar.gz/md5/2d56a5cfeae0a6afa2d2b8efa1ab22c5 +OpenBLAS.v0.3.28+0.i686-linux-musl-libgfortran5.tar.gz/sha512/e81207bee11f89669837db08b57b63813056730f68412345421539399c12a675ed01942558ebd42045959c29a2b774a75f28c4a6b14549b7373b54a5e93e8933 +OpenBLAS.v0.3.28+0.i686-w64-mingw32-libgfortran3.tar.gz/md5/5b741b5fec8b564ba8b24435b5d885ae +OpenBLAS.v0.3.28+0.i686-w64-mingw32-libgfortran3.tar.gz/sha512/97e72a4b9b39d4889c4e36eff85186fcbabfff2930185e69b3c259b43cdbaa5fab51bf0ed4024d1ddd3c780edaf501c4f5f7534e0a2edb802d580987fbd026ab +OpenBLAS.v0.3.28+0.i686-w64-mingw32-libgfortran4.tar.gz/md5/d5f059fc960b7dc84ee4b92c431d87b4 +OpenBLAS.v0.3.28+0.i686-w64-mingw32-libgfortran4.tar.gz/sha512/f1e8f31f89274ff5b466931f8941de55fb27d2ee773d87e7e0b992deeec7d921358b10520cc0f47975022536b5e9d7b1cc9acc481b95f83cc2096d7cb7494616 +OpenBLAS.v0.3.28+0.i686-w64-mingw32-libgfortran5.tar.gz/md5/cb99d7d4944c5283a1a0142683e1d377 +OpenBLAS.v0.3.28+0.i686-w64-mingw32-libgfortran5.tar.gz/sha512/b77d3225e60f49506917bfff78c187df7157dbc834eccda2fa03d03eef8214b225682888a411a8b6e4b29a8d7e2b0ca625ea8c56b84ecc39e1f4f1012523c096 +OpenBLAS.v0.3.28+0.powerpc64le-linux-gnu-libgfortran3.tar.gz/md5/c6e5d4867a068e08b3f56f474e498b81 +OpenBLAS.v0.3.28+0.powerpc64le-linux-gnu-libgfortran3.tar.gz/sha512/de6249439758a501bfd27d3ef04ec04cc06edf64de73f0709a6a40a2eaf40bd3d5d77dfd54b7b19e2f6bf6c104b4416d3e225faa0cff4cb631785c08d90b8614 +OpenBLAS.v0.3.28+0.powerpc64le-linux-gnu-libgfortran4.tar.gz/md5/32e70466cfa3cfec65ab4cad3abc5f03 +OpenBLAS.v0.3.28+0.powerpc64le-linux-gnu-libgfortran4.tar.gz/sha512/2642385a5e9fc8e9c3839a5a44f9753b21b5078725f7d0c3e1ebe96b76129a3b8e2627d92629dee4f6fd7e8e51e86a7fbedc80cbe4d1a6812cea363559950da0 +OpenBLAS.v0.3.28+0.powerpc64le-linux-gnu-libgfortran5.tar.gz/md5/e2332831bd88d57132241697952819e7 +OpenBLAS.v0.3.28+0.powerpc64le-linux-gnu-libgfortran5.tar.gz/sha512/ad03edf9ac56bf6311f0ca70a1bc359242accfe82cba9e42f39f6cb1c3006226179ff9be8218847889cae10fac13bc33f60837e1e3249e309172da7fbc25400f +OpenBLAS.v0.3.28+0.x86_64-apple-darwin-libgfortran3.tar.gz/md5/24c915a3156983745662ff99e5d1b040 +OpenBLAS.v0.3.28+0.x86_64-apple-darwin-libgfortran3.tar.gz/sha512/47fb327281c903eebb0a261458fc10f09bac317d7e135dff72a112c868a2525fa542f93f22da083c13454fc241352d39a8e8463085685aa77e055ffcadf451c8 +OpenBLAS.v0.3.28+0.x86_64-apple-darwin-libgfortran4.tar.gz/md5/93041d21ad3f95e6d9cbac6cd6730363 +OpenBLAS.v0.3.28+0.x86_64-apple-darwin-libgfortran4.tar.gz/sha512/17cd2302860eeee884f97d87eaf0ad12cdc7361734cfaa77b543119c58103a5da107b478e7ecfcb135d2e5beffd6a3907108b2911a095a3cbc1d16f32371ac1b +OpenBLAS.v0.3.28+0.x86_64-apple-darwin-libgfortran5.tar.gz/md5/98a8c6c8c80c11e8b6d127959c9b3414 +OpenBLAS.v0.3.28+0.x86_64-apple-darwin-libgfortran5.tar.gz/sha512/d26a51785391d81efcaefcf647fcf0348ad68ff01845ab3547778903d2ab5c5c1cdb2a562ae5cf7f12878f3345c46321719ea82fb87ef655d303a4c0c9803377 +OpenBLAS.v0.3.28+0.x86_64-linux-gnu-libgfortran3.tar.gz/md5/41f7fdc10d8cab0965da95e00e2269ba +OpenBLAS.v0.3.28+0.x86_64-linux-gnu-libgfortran3.tar.gz/sha512/0a47ef77f9b2b70f424e00957f676c53d19c5dffbbcd5a743ab24bbc8608c5e8ad3cb3afefd8cab60a3c51970a63dd47c97868ecc0ef3532b83278c41a8daf96 +OpenBLAS.v0.3.28+0.x86_64-linux-gnu-libgfortran4.tar.gz/md5/8453e7a5e5285e770fde7592582bc0e2 +OpenBLAS.v0.3.28+0.x86_64-linux-gnu-libgfortran4.tar.gz/sha512/a37edfe68c85a6312d7918f1b58d6ac4bafc13081dbd327c830631913350a54bbf8bea57115b4f242d5f93c6b0a8f4995b5ef544a0de06e76c66287ff092e74c +OpenBLAS.v0.3.28+0.x86_64-linux-gnu-libgfortran5.tar.gz/md5/6df24890be7a4899f35a2949f9f21d65 +OpenBLAS.v0.3.28+0.x86_64-linux-gnu-libgfortran5.tar.gz/sha512/66601632f91689fe72afecd2e4d4ef3ad3b7653874228d5509c7732f2e6d63640f35d176ce2219b732632e0daeb76dc3ba11d3e776639985359b21b313056883 +OpenBLAS.v0.3.28+0.x86_64-linux-musl-libgfortran3.tar.gz/md5/d35df8d213c55bc1f9f765e0ba8c7b4e +OpenBLAS.v0.3.28+0.x86_64-linux-musl-libgfortran3.tar.gz/sha512/5d5de73150a2e796dc29425dbf415ff7aa443264d767d4e688de07335961ee39835c94b7d68900d49b70bf3ac08d356f3ae00c6d651eed64e504b02c9351edcb +OpenBLAS.v0.3.28+0.x86_64-linux-musl-libgfortran4.tar.gz/md5/384f9173b3804e6f9c73bcde9dacb545 +OpenBLAS.v0.3.28+0.x86_64-linux-musl-libgfortran4.tar.gz/sha512/64d3abeca401cee06575915161458408e9fb51e26f759129e1c7a9c27f68729d66e75f0654b977e842844650698c4b1627a18e495d91202a8c0483ef1b35bafc +OpenBLAS.v0.3.28+0.x86_64-linux-musl-libgfortran5.tar.gz/md5/0bd296248e1337fac054b9e0993fea82 +OpenBLAS.v0.3.28+0.x86_64-linux-musl-libgfortran5.tar.gz/sha512/fdb9ce296228f92c112bbeb346a2900a8d5a73e21a313a217cf7135fd77484cdeed53c86382ee5550f1b624eb6ed99d06b739229add7364217ca68fefedd04c4 +OpenBLAS.v0.3.28+0.x86_64-unknown-freebsd-libgfortran3.tar.gz/md5/524a2481331fdd3933f06b40e63433f1 +OpenBLAS.v0.3.28+0.x86_64-unknown-freebsd-libgfortran3.tar.gz/sha512/06831cc855e9801dbf2248a0da123c345b6731c830f39d3166b8d8e7de8d649b6d9900e534ec6c1113a227203f6a9aa8171fcf548cfd56a4a67b6037c105ecf5 +OpenBLAS.v0.3.28+0.x86_64-unknown-freebsd-libgfortran4.tar.gz/md5/82f2b8f31f7b718f6ea743c996acbe4d +OpenBLAS.v0.3.28+0.x86_64-unknown-freebsd-libgfortran4.tar.gz/sha512/fd1ccab964ae9410238d29b38cfe8c2ccca3fda3d78b4294bb4a54ab8abfd6bdaa80cadc0aeadf054bf99138c5dc3cac9370920b0b16cb8793630ab21d5bf667 +OpenBLAS.v0.3.28+0.x86_64-unknown-freebsd-libgfortran5.tar.gz/md5/b91add21ba0e2a0f28a9e4d347111cc3 +OpenBLAS.v0.3.28+0.x86_64-unknown-freebsd-libgfortran5.tar.gz/sha512/8ed1d9e327529ee067d975c5c96dac3eabab5a88ed7b1b6e1b030f96bbd2418e3173cacd70e9976d619245757f2a34cc9527aafef1626fd288f14918c9b13eaa +OpenBLAS.v0.3.28+0.x86_64-w64-mingw32-libgfortran3.tar.gz/md5/937847e2ad00539f3422d1ecb9d26d55 +OpenBLAS.v0.3.28+0.x86_64-w64-mingw32-libgfortran3.tar.gz/sha512/751d889661ddd46cd5718b49e34f826a4fb34b1b992251a5a975bc0af15b74a75d8a56f403e8fae570223477b2b8927d9cb36764e4b9e466045d5f317b8e7196 +OpenBLAS.v0.3.28+0.x86_64-w64-mingw32-libgfortran4.tar.gz/md5/180c54c50362d05696589b270693ee8f +OpenBLAS.v0.3.28+0.x86_64-w64-mingw32-libgfortran4.tar.gz/sha512/2e3b76be5b7c4a7dc45f07e17493abd7ef9185e92429d8fa4d38766e0da96dd0777b619a9e420d2e1142bdab2ae1f755f9bc9ad97ee9a7927741778f89b9135f +OpenBLAS.v0.3.28+0.x86_64-w64-mingw32-libgfortran5.tar.gz/md5/2f0fac7c96af66ea63fce26e409f4db6 +OpenBLAS.v0.3.28+0.x86_64-w64-mingw32-libgfortran5.tar.gz/sha512/141522971447c38b4908342f3ad09ffb18142d2e79b44f66fd80047b44c09216c9b94c39f776e3093f9ceb6bc4d6270cbbfb4209b2fc0debfe93e7145cb4dbff +openblas-5ef8b1964658f9cb6a6324a06f6a1a022609b0c5.tar.gz/md5/f7a1fe86cefbf7d4f2608843c7833ca7 +openblas-5ef8b1964658f9cb6a6324a06f6a1a022609b0c5.tar.gz/sha512/5f6020e958967a12a3c5b18bde13331f9c0602bd073563f35cd7cec848c92b45f30ca362819b12cd16989c0e4641ee3e63db8322d1092f61b31ba2e4068dd7a7 diff --git a/deps/checksums/suitesparse b/deps/checksums/suitesparse index eec27cb539d0f..acec99b39879c 100644 --- a/deps/checksums/suitesparse +++ b/deps/checksums/suitesparse @@ -1,36 +1,34 @@ -SuiteSparse-7.7.0.tar.gz/md5/e659373ed5e9b961d2fcb6d67d250783 -SuiteSparse-7.7.0.tar.gz/sha512/aa62dae81ae423ce7162ae83b46e5cf606d95482e6c6bb7ae6d61e15987761119d9418ef3a96648e6ba2327871a2847eef8ace197aa375279d71c80329d6f451 -SuiteSparse-e8285dd13a6d5b5cf52d8124793fc4d622d07554.tar.gz/md5/46541001073d1c3c85e18d910f8308f3 -SuiteSparse-e8285dd13a6d5b5cf52d8124793fc4d622d07554.tar.gz/sha512/f7470a447b934ca9315e216a07b97e363f11bc93186f9aa057b20b2d05092c58ae4f1b733de362de4a0730861c00be4ca5588d0b3ba65f018c1798b9122b9672 -SuiteSparse.v7.7.0+0.aarch64-apple-darwin.tar.gz/md5/276f7355e36eeab2911a141e5570dede -SuiteSparse.v7.7.0+0.aarch64-apple-darwin.tar.gz/sha512/72aa979c3a4f6d2fa65f4d16ab106a7b306f5e84da91bf04a7a11bd863f71a8386ca5248b7e3fde83347cf912fae8ec3c87617db09f6bfadf12c476061855d28 -SuiteSparse.v7.7.0+0.aarch64-linux-gnu.tar.gz/md5/4c3ab9c8c451198420516bd84fdd079f -SuiteSparse.v7.7.0+0.aarch64-linux-gnu.tar.gz/sha512/7afb088a9b117f79531d828a458419e0e8901daa635eeb1b5c753d60c26784496095f2bf70c5c3dedfc5a1c8dd04c56cd8408667fedcbd06abcec0a41a1171bb -SuiteSparse.v7.7.0+0.aarch64-linux-musl.tar.gz/md5/e12af599488fa7578fb8f2018969f4c5 -SuiteSparse.v7.7.0+0.aarch64-linux-musl.tar.gz/sha512/c9e1c2938754dc3b7704e373f36cc876b592acac06c945860958e56f26e09b7be6ce58c4a9184d3528bcc1458d1f7ab9bd605b9a11083419e849e9fa2cc93f2b -SuiteSparse.v7.7.0+0.armv6l-linux-gnueabihf.tar.gz/md5/a3912a6af26ff19d3fcd166d8426f1ff -SuiteSparse.v7.7.0+0.armv6l-linux-gnueabihf.tar.gz/sha512/5f724f5cfb526f2db7d184976f1711f09f77d548593ef9c28ae98a15b6927303864535761929fcd729448d9ece8a7f599cf82d0a83a7668966bdd8b6b62b641f -SuiteSparse.v7.7.0+0.armv6l-linux-musleabihf.tar.gz/md5/24ab4184bf83e59e029cf950be56f1c5 -SuiteSparse.v7.7.0+0.armv6l-linux-musleabihf.tar.gz/sha512/9f1b05c48b051b3c0440e7075f84105a5c5e8e2c8685d93fac847e1cbbf5427ba623ecde16d9b2293b0c286326bfbce07f8d2906a892065fa9fe3d36a4c0386b -SuiteSparse.v7.7.0+0.armv7l-linux-gnueabihf.tar.gz/md5/8433d1206bc72053c1936a1e5f76ea30 -SuiteSparse.v7.7.0+0.armv7l-linux-gnueabihf.tar.gz/sha512/d5f3249db8bb3a4f216d3abef0416e090c1b4d0a847d814df03f3585159602a31b8e4edffae36c3cc39b5c79691c15d51a085b746f03b86d9a0a9b18d00332d9 -SuiteSparse.v7.7.0+0.armv7l-linux-musleabihf.tar.gz/md5/8651a96c9b5617287c917b07d9f6fb16 -SuiteSparse.v7.7.0+0.armv7l-linux-musleabihf.tar.gz/sha512/3e3f21083a8cd26919d6592be41f531ce4293a9e05a84d5298a4d6c3c222892d6d364c30c75558a1461020ac5446fd51e88a333d03118d74eb28ea33a3386d3b -SuiteSparse.v7.7.0+0.i686-linux-gnu.tar.gz/md5/184c95889dfb07319b9ee51e2ff12d0e -SuiteSparse.v7.7.0+0.i686-linux-gnu.tar.gz/sha512/5424a42418e033c67e0868dd7878990158a9f099f2e3ed04aed45c6ceff0a828080df6eae004e10a3784136f66ac13da46df0b3bb3c96fc32c7bdf02830af41f -SuiteSparse.v7.7.0+0.i686-linux-musl.tar.gz/md5/0bde5fe930ec4e2e90945b6bfd78e8d2 -SuiteSparse.v7.7.0+0.i686-linux-musl.tar.gz/sha512/1ff4c8e578146cca72c1bd74cddbba5999053e5729fdb217b0e4f1c0d5cbcae5a73f466e72a52e92979e5f8cc2549b1c5222c7ca32b628db0b71e129a2d22714 -SuiteSparse.v7.7.0+0.i686-w64-mingw32.tar.gz/md5/5439e41ed1909ffe4ba28669eb45ef43 -SuiteSparse.v7.7.0+0.i686-w64-mingw32.tar.gz/sha512/380999433f0a2c1d65a1bf6ea48da60e6cead831cfc31ab3df0ba122afbc32b2e14fb3d8d578a909b9f39f2763923816a691863756996ea064a595e58a788b98 -SuiteSparse.v7.7.0+0.powerpc64le-linux-gnu.tar.gz/md5/ea08ebbd5aaae629a194450c25a77d2e -SuiteSparse.v7.7.0+0.powerpc64le-linux-gnu.tar.gz/sha512/cfe6675e6a6b7790de8a6a3de2dbf561770fa63113c66890a3f888fba71e20c77edaa89b23cdf0038f3a870be9bd5e351aa84b774e7da833c9c0c90e05c0e9fb -SuiteSparse.v7.7.0+0.x86_64-apple-darwin.tar.gz/md5/314a033b51d6d239e29a91fcca911260 -SuiteSparse.v7.7.0+0.x86_64-apple-darwin.tar.gz/sha512/77147381738484d147ce529b4e9d3dff9bccbe5ed07071b5df647a785f118e46792f739f145d597ef78c871d75759348109ad3e08125fb58dd12b8a6813a8fcc -SuiteSparse.v7.7.0+0.x86_64-linux-gnu.tar.gz/md5/f62f17fc50b15e0a4a117f77c52b35f3 -SuiteSparse.v7.7.0+0.x86_64-linux-gnu.tar.gz/sha512/0ba022a5d0039b1348a09521cc2bd366df8c6603a7d3de4bf7d1b15504add8607bf5fa2bcf7d95b2b48cb676c17cc516903323615b6a668e53310363a3f6b242 -SuiteSparse.v7.7.0+0.x86_64-linux-musl.tar.gz/md5/d9b77034590bb0511f2ea2d726303f94 -SuiteSparse.v7.7.0+0.x86_64-linux-musl.tar.gz/sha512/a1149ec6f50b978b1bad91662035d8d131d431459e1910b2cd9fe0307f50d23ca15148f1af522db04327e8cc9cc7c04f85852ddb606ac82fa346b4ab70d28752 -SuiteSparse.v7.7.0+0.x86_64-unknown-freebsd.tar.gz/md5/7b7f00672f0880e397a5182da084c334 -SuiteSparse.v7.7.0+0.x86_64-unknown-freebsd.tar.gz/sha512/06696d78cd7e385906e2fbfbd8ec804de5a4a3d8134d30bc105f713eb915742204e4226229b33a93740f30a3ff24d48dde651e64a78bc6d937e84ce484f6dd74 -SuiteSparse.v7.7.0+0.x86_64-w64-mingw32.tar.gz/md5/91b2e33ead8c2898881475ddfe202987 -SuiteSparse.v7.7.0+0.x86_64-w64-mingw32.tar.gz/sha512/cb5f2caff872ba2ab66f1285e264b4c28ec0a05a4a0fea3964c22aa167195b57a9d9de2c9b9289438459c6b1c1b9f047807414b3e1305e87642edabd22973bd6 +SuiteSparse-7.8.0.tar.gz/md5/ad42a80d28bb56a1fce15f6e7332e04e +SuiteSparse-7.8.0.tar.gz/sha512/91aff0aee26e938ba88a8f92db15b0db0ecc6ada3b60153bb299f53a45ccda131db4bc66f890c220034c900180d0bb3a5fb3e2686fec7d6174f5900a3ee64424 +SuiteSparse.v7.8.0+0.aarch64-apple-darwin.tar.gz/md5/38379e14a53663a9c23f32ed56801676 +SuiteSparse.v7.8.0+0.aarch64-apple-darwin.tar.gz/sha512/3f2a7aa7778a22d150bad9ecb8d03edfa75707a07545e65660c8ccc4b0a9fb058ccab29e21e4728741d40d390d28922d521d3841e16258cf8e26acacadfc1fbd +SuiteSparse.v7.8.0+0.aarch64-linux-gnu.tar.gz/md5/bc52c7df0a442c0fb9aafb83d60878f4 +SuiteSparse.v7.8.0+0.aarch64-linux-gnu.tar.gz/sha512/436e79ea0774d6ffb571b513e385ef48d9cc70b72010cffdc23d606ad6c8984c8b49e2422ce8881def0722f3f608e4ecb87e6752dd80cf7988addd330c5ded13 +SuiteSparse.v7.8.0+0.aarch64-linux-musl.tar.gz/md5/87e4c2588efc39723621ac5010ddf2e5 +SuiteSparse.v7.8.0+0.aarch64-linux-musl.tar.gz/sha512/17115826716bb48f16e4593941be275d47012d112e54d8826c75fde119ffc9f66accd02353b309365b59779d7af3ac220f31ab7cf7eea165b209a93ecdc4102f +SuiteSparse.v7.8.0+0.armv6l-linux-gnueabihf.tar.gz/md5/b1490603aa129942d8e4c9581853cd0a +SuiteSparse.v7.8.0+0.armv6l-linux-gnueabihf.tar.gz/sha512/e23c3532784e295ae72b811d285c3729c3f8ac1b5ee1621e831b6b2824a5b357e4bfa49e09174de7763fc3ebcab6b84ef16536bc1cf6f4bc0543b1b229209178 +SuiteSparse.v7.8.0+0.armv6l-linux-musleabihf.tar.gz/md5/f8199358882f76dd30bcce741b837de1 +SuiteSparse.v7.8.0+0.armv6l-linux-musleabihf.tar.gz/sha512/2c8d4ec21bfe253d3d32a5f5f09601b9b2864149f63f53067b157f5f7315fb04236bf5b19a1e5b4569e2c73127dcbb1703d56c7d06fc3ab9ae155902b7a1c2a9 +SuiteSparse.v7.8.0+0.armv7l-linux-gnueabihf.tar.gz/md5/cc3aa1a013cc91e7076dddf20fba9f60 +SuiteSparse.v7.8.0+0.armv7l-linux-gnueabihf.tar.gz/sha512/a6b8cfbc345a089f12e55d8d44061dcce30f94c2d79fc520d6c5dfe433ac2e362d049fac72278cb59d4b3760ca08d5e350b7e2658fa5e8c77ce8608f67c2c4c4 +SuiteSparse.v7.8.0+0.armv7l-linux-musleabihf.tar.gz/md5/0d7797d31c30c53bf219cdc0a48e64dc +SuiteSparse.v7.8.0+0.armv7l-linux-musleabihf.tar.gz/sha512/a7df8938ee6a04f62169bedd29c8408951cf33a43e0f529fb4d1e360bdad6462a50b2af297adb5f51fd726e1ced1fc8fcda7feeeafbeb44000bfe02a8e29c29e +SuiteSparse.v7.8.0+0.i686-linux-gnu.tar.gz/md5/e48fa3d2e00f210e964c21e4ff27efae +SuiteSparse.v7.8.0+0.i686-linux-gnu.tar.gz/sha512/3088c2af476285eb8549cf6aa56381156d49513a274348f86fbf01aa9ce0712961471f83fa50b261f3f365a302b88eb20ef0bb35b58c07a2cfb5dc337fdb72c1 +SuiteSparse.v7.8.0+0.i686-linux-musl.tar.gz/md5/e55202dbeca107a0c25a4f09d5d68915 +SuiteSparse.v7.8.0+0.i686-linux-musl.tar.gz/sha512/0f4de2e62016914b4d1bcb9b13bd8cb2bebefc5f0a532e103948b9aae79a20462ac7b74a3e968d4f99076c37dbbafb747699cd151e831ff89d297f78478fb84f +SuiteSparse.v7.8.0+0.i686-w64-mingw32.tar.gz/md5/cb971bc1042196e527f95015c8bc5ef8 +SuiteSparse.v7.8.0+0.i686-w64-mingw32.tar.gz/sha512/d445a7790e3ac5392f75c9f4ec30cd1c812354b04388b4c6c6cea2423d2f0dac7173b17a8a2b7a7f4af10321601f96819a7702f9beac0397d85916d99493bc39 +SuiteSparse.v7.8.0+0.powerpc64le-linux-gnu.tar.gz/md5/12058f122b548a37070770d1847f3ce9 +SuiteSparse.v7.8.0+0.powerpc64le-linux-gnu.tar.gz/sha512/f375feeb8448ea90ce8d9f31c7e1230f6868316f06094ba0155069dded4f8da2e1b54d462ef9cfc77abd76147740d4066236dcf1fcea91f8a7141819962ad0ae +SuiteSparse.v7.8.0+0.x86_64-apple-darwin.tar.gz/md5/1bd473f2a25f1ebcea8acc858e2594b4 +SuiteSparse.v7.8.0+0.x86_64-apple-darwin.tar.gz/sha512/034af137deee5bf0ebf3746745d09ad50ce135cd4768a2049bb9811478ff90e6ed8e2c990e277b4c3b38a3a5e9eaa856938eb86239ca445fa64b6dab6af7e996 +SuiteSparse.v7.8.0+0.x86_64-linux-gnu.tar.gz/md5/c58a86d9f25e6705941105d9e41f084c +SuiteSparse.v7.8.0+0.x86_64-linux-gnu.tar.gz/sha512/56447062802f01815ffb014624423c6fd3ab6e16b642b2fe37972a151b02865965c95ca3d1a455c6d51cd31633aea8a732b235b55d68e6779c17b293c488fa43 +SuiteSparse.v7.8.0+0.x86_64-linux-musl.tar.gz/md5/ba6e10ba61c209df94f18ab51fe2dd90 +SuiteSparse.v7.8.0+0.x86_64-linux-musl.tar.gz/sha512/3b8fc504cfb4a3b628d5b955a482bad08c85e09e529f833855a84b847721247aaa469f96adef6b218a1ba5896cde91664cc819ba33115e3cc309e72140841ca3 +SuiteSparse.v7.8.0+0.x86_64-unknown-freebsd.tar.gz/md5/a50c69142a42c14edac4ce94b86b138a +SuiteSparse.v7.8.0+0.x86_64-unknown-freebsd.tar.gz/sha512/963be0dccd1a594df08fe5135ef4ac13e1d707841c3e97d31ba5477d0d6ec26bad9be1c52d9fd78f199740a53950353adbdd767469f3bf01ea1e3ee843eb6c1a +SuiteSparse.v7.8.0+0.x86_64-w64-mingw32.tar.gz/md5/7ca11ba89bd09183cc5a9320d6e8a4a7 +SuiteSparse.v7.8.0+0.x86_64-w64-mingw32.tar.gz/sha512/e1d5def1103bbf0bb29c08cdd3bf21ba60456353694985c66f8e55a31d54a32c5b891e56e1ffe30f9e1223c49283d267e483e2f1b999f566099c239b3eed1d78 diff --git a/deps/checksums/terminfo b/deps/checksums/terminfo new file mode 100644 index 0000000000000..bd971e72b1be8 --- /dev/null +++ b/deps/checksums/terminfo @@ -0,0 +1,2 @@ +TermInfoDB-v2023.12.9.any.tar.gz/md5/573d9b5adaf6af500e3dfae6e3d15ebf +TermInfoDB-v2023.12.9.any.tar.gz/sha512/e0a5bfe54346f9d5690a840628b329f6fac7375b0d29337bc70813ae3553a72bb397f8034d221c544289e40c4cfc685d5805777b7528f05bbe0123b5905c24a4 diff --git a/deps/checksums/unwind b/deps/checksums/unwind index 7ef31e6bda06b..317809053abeb 100644 --- a/deps/checksums/unwind +++ b/deps/checksums/unwind @@ -1,26 +1,26 @@ -LibUnwind.v1.8.1+0.aarch64-linux-gnu.tar.gz/md5/e25a186941b2bedeb4a0fca60b1e5d1b -LibUnwind.v1.8.1+0.aarch64-linux-gnu.tar.gz/sha512/4b488ef13b1b09d37dd2d2f62647e6407404730beb8cab58263c2d8e9db3716bfdb8949eca8ebb126eb22a3fcd81deb7ea0774fe7527ba7374f76047fe03abd7 -LibUnwind.v1.8.1+0.aarch64-linux-musl.tar.gz/md5/75fea80870d951a5e87d37bc67e52cfb -LibUnwind.v1.8.1+0.aarch64-linux-musl.tar.gz/sha512/efb54577cddaf5e7930b15cdd98ed88e4d60ba3a1fe0097b2a64a868f92177985c71a86cfb40475976005ab55a01401960afa9c20649b1e34ea02ef262caa046 -LibUnwind.v1.8.1+0.armv6l-linux-gnueabihf.tar.gz/md5/30f3077b185f6e51b8b6ddfddcb8effb -LibUnwind.v1.8.1+0.armv6l-linux-gnueabihf.tar.gz/sha512/524810edbcfcba4938cb63c325905569b7d232dd8b02856e5f1592d7e36620c3ee166c0c788e42a14abc281c41723f49563f59d8cf5175ae1c3605ec29a97b9f -LibUnwind.v1.8.1+0.armv6l-linux-musleabihf.tar.gz/md5/087d263a8edacec1b79d4eccef03ab53 -LibUnwind.v1.8.1+0.armv6l-linux-musleabihf.tar.gz/sha512/bad2bea6f98ed9e0ac293ab3cd7873d2c164616bd09103ad773300da1875e28ac51744809629d01b69744c610d93c90cc48ec4c81411b5d3f036db86e098adcd -LibUnwind.v1.8.1+0.armv7l-linux-gnueabihf.tar.gz/md5/218f8a37d910bcfaba1bbeb9f61593a1 -LibUnwind.v1.8.1+0.armv7l-linux-gnueabihf.tar.gz/sha512/1912b7aa4bbcaca3facad13bf9a8a8b4bb42183b9c542c6b51f0f4a715c27b7583dcf36f49a1fac9787ba7b39728a5d1a151661a570ef637d1080c11d5426fc4 -LibUnwind.v1.8.1+0.armv7l-linux-musleabihf.tar.gz/md5/c2582785ca7dc2edbc529a93ea0f4120 -LibUnwind.v1.8.1+0.armv7l-linux-musleabihf.tar.gz/sha512/ae5414a274d973623070402806eb279dd2ab708c801fa7f24ba9b8066e7fc13ae9ebe1f331f76dd54a4eba572e87117c57d502190b63978af87d7fa35a011632 -LibUnwind.v1.8.1+0.i686-linux-gnu.tar.gz/md5/324ae0c4916a435a6746ca77a1034b58 -LibUnwind.v1.8.1+0.i686-linux-gnu.tar.gz/sha512/fe5ac30e6cdda9f99c873a7af60407c5f1ca1d17396ab46679df56093fea37289e802dd53ed083a4963f7439a1887b4d401a9ab489bdeddd2d003b761af84c1c -LibUnwind.v1.8.1+0.i686-linux-musl.tar.gz/md5/0495beea1d8e5e4572f32830125cb329 -LibUnwind.v1.8.1+0.i686-linux-musl.tar.gz/sha512/3db7f9241e11e139f02239826a65f40d77d968aa7dde574cf91759706dc9a5c97fb055b34ec011f9ac085eec121c3807e9c873773d1ab091a5a7180200ea73ec -LibUnwind.v1.8.1+0.powerpc64le-linux-gnu.tar.gz/md5/1f0feb7cced4b847295dff4c1cd0dde1 -LibUnwind.v1.8.1+0.powerpc64le-linux-gnu.tar.gz/sha512/88707b4a45e3de2901a343f20a35d2003d24db6604a5194712a3a687299b98e7507934a1bd4d7a21f84f089e0378964334c483f10311dd1bfbaa5d8b42ab9f76 -LibUnwind.v1.8.1+0.x86_64-linux-gnu.tar.gz/md5/a03c84494c04ba08fa7e314584d28945 -LibUnwind.v1.8.1+0.x86_64-linux-gnu.tar.gz/sha512/eb97ec8cf03fc5cb77a6218fcc4f1ef1266e66a774dea34e1d1fb7f89c026287bb4bd09de0b61a83b42495b8b4d5be475a61b4df68c83bfb33be2145ed659627 -LibUnwind.v1.8.1+0.x86_64-linux-musl.tar.gz/md5/194654cfd8d202599b7096783659c0ab -LibUnwind.v1.8.1+0.x86_64-linux-musl.tar.gz/sha512/f39f8d0488ec02d9693b4a17ca73ec683ea062cfc67400d02e1e38bfeb43c371068742379d5e17f8c8b4ab478de48f91284e17b0e1b94e09d1a64713276326c7 -LibUnwind.v1.8.1+0.x86_64-unknown-freebsd.tar.gz/md5/6453d66204ba5fb941046afd85345b90 -LibUnwind.v1.8.1+0.x86_64-unknown-freebsd.tar.gz/sha512/77e67c3ddda5eaee0e8b127ad8e2ad41add4410e356c4e4b9bc46eb19871b91d006a59009d9948c4cc0951c2d9e956a99c946a60ba47ceb7f827b2897d6939e5 +LibUnwind.v1.8.1+1.aarch64-linux-gnu.tar.gz/md5/0f789b9e5b2604a39cc363c4c513a808 +LibUnwind.v1.8.1+1.aarch64-linux-gnu.tar.gz/sha512/4c9c8250bfd84a96135a5e9ecdd4500214996c39852609d3a3983c2c5de44a728d9ce6b71bd649c1725e186db077f74df93a99f07452a31d344c17315eedb33d +LibUnwind.v1.8.1+1.aarch64-linux-musl.tar.gz/md5/356deb10e57d4c7e7bf7dbc728d6628d +LibUnwind.v1.8.1+1.aarch64-linux-musl.tar.gz/sha512/a998eebe7a4928bd417620bef0de9728c080f5d9714f15314ac190b333efa1bd7a21207156d56c132515bd3f7154d60204f1fac2dac5468560a7017682527c78 +LibUnwind.v1.8.1+1.armv6l-linux-gnueabihf.tar.gz/md5/b0ff12f5f0c801e5e280a142a1b7a188 +LibUnwind.v1.8.1+1.armv6l-linux-gnueabihf.tar.gz/sha512/68003f39eaf55c8742e821a228889590e8673cbafb74013a5b4f6a0c08ee372cb6b102a574e89ce9f46a38dd3d31ef75de95762f72a31a8ec9d7f495affaeb77 +LibUnwind.v1.8.1+1.armv6l-linux-musleabihf.tar.gz/md5/b04c77d707875989777ecfed66bd2dad +LibUnwind.v1.8.1+1.armv6l-linux-musleabihf.tar.gz/sha512/fb20586a0cbc998a0482d4102d8b8e5b2f802af519e25c440a64f67554468b29c6999a9ec5509ba375714beb93a4b48e8dbf71e6089c25ecd63b11eead844041 +LibUnwind.v1.8.1+1.armv7l-linux-gnueabihf.tar.gz/md5/e948016b4179d34727b456bc768cd8e1 +LibUnwind.v1.8.1+1.armv7l-linux-gnueabihf.tar.gz/sha512/6fc64e8ac7248540b95c321103d234f2c8633087f261e368251fe2cf6ea4e0654325716ac7017ae966edc4ddbb004a0f808d6e25cca766faaf505ca1f8f4aee7 +LibUnwind.v1.8.1+1.armv7l-linux-musleabihf.tar.gz/md5/660cf49c34a2ead1afbdcb44491e174a +LibUnwind.v1.8.1+1.armv7l-linux-musleabihf.tar.gz/sha512/edf337d176440c210f5860e90771758335256fe9d2f179d506656bccf92a9f9aa478d176d4b0db2213945ae847dad5bb88265110c92cfcd538d5740858b6a3f0 +LibUnwind.v1.8.1+1.i686-linux-gnu.tar.gz/md5/7032a70cfecb88cdd49cc3a4879456c6 +LibUnwind.v1.8.1+1.i686-linux-gnu.tar.gz/sha512/e34acc8f270c5156ede3ac3377d0f428c672daed869570734351c6b5a8946d65b5c0c041b713dddefedef81e55c65f5683aed0fec0d366e2d0207d8b902b0e33 +LibUnwind.v1.8.1+1.i686-linux-musl.tar.gz/md5/0541c3419020334173d299cf3482ff85 +LibUnwind.v1.8.1+1.i686-linux-musl.tar.gz/sha512/0b57745d280fb9893772936cd4872b0e04f41d86379e772b889e75baffe9324ef8dd168bb4c9761c1b8372f387ce99721dd6086b1d52b9a91215f40e8113968d +LibUnwind.v1.8.1+1.powerpc64le-linux-gnu.tar.gz/md5/fee37734fe95d1e96ebc77316df64192 +LibUnwind.v1.8.1+1.powerpc64le-linux-gnu.tar.gz/sha512/953ef70fb203db73764eeab0a37521b94e79ce70644ae16fe3157ca8d1011a0319d1928d094a3e2ed1e0489fdc0ca7dda33722095fd3aa40ed1fde150cf44c2a +LibUnwind.v1.8.1+1.x86_64-linux-gnu.tar.gz/md5/bbb201e7455fd13b805b0a96dc16183b +LibUnwind.v1.8.1+1.x86_64-linux-gnu.tar.gz/sha512/b1e21f7d772bd15bada17d287e1876ae586a97c6a8669e714347e7bf8a9b202fe53e8559cf19358f88bc458b2fe15ccbd616b64163cc715ce253f43f5133a8cd +LibUnwind.v1.8.1+1.x86_64-linux-musl.tar.gz/md5/72156f9d6da9a2742d9152822e5525f5 +LibUnwind.v1.8.1+1.x86_64-linux-musl.tar.gz/sha512/53a3f1985c5ae4816693f292604810cbe948e6332aeb227fb900ba3730f4379e863b144ae87af2c0651c2b9633b35c45c7a0a6fa34958dc9f58e0f8baa2ea701 +LibUnwind.v1.8.1+1.x86_64-unknown-freebsd.tar.gz/md5/e4346df03246d847f2867df3ab5ac624 +LibUnwind.v1.8.1+1.x86_64-unknown-freebsd.tar.gz/sha512/ee01bc12726288ae091476c1bed44de224a9ef5355687fd6fd64742da6628450434d7f33d4daf81029263aa6d23549a0aa5c5ae656599c132051255d1d742d5d libunwind-1.8.1.tar.gz/md5/10c96118ff30b88c9eeb6eac8e75599d libunwind-1.8.1.tar.gz/sha512/aba7b578c1b8cbe78f05b64e154f3530525f8a34668b2a9f1ee6acb4b22c857befe34ad4e9e8cca99dbb66689d41bc72060a8f191bd8be232725d342809431b3 diff --git a/deps/clang.version b/deps/clang.version index 76ddb503b3c8c..fcd55b72de5ff 100644 --- a/deps/clang.version +++ b/deps/clang.version @@ -3,4 +3,4 @@ ## jll artifact # Clang (paired with LLVM, only here as a JLL download) CLANG_JLL_NAME := Clang -CLANG_JLL_VER := 17.0.6+4 +CLANG_JLL_VER := 18.1.7+2 diff --git a/deps/curl.mk b/deps/curl.mk index 444334b581fed..ae2830c3cd4f2 100644 --- a/deps/curl.mk +++ b/deps/curl.mk @@ -37,7 +37,7 @@ checksum-curl: $(SRCCACHE)/curl-$(CURL_VER).tar.bz2 # Disable....almost everything CURL_CONFIGURE_FLAGS := $(CONFIGURE_COMMON) \ --without-gnutls --without-libidn2 --without-librtmp \ - --without-nss --without-libpsl --without-libgsasl --without-fish-functions-dir \ + --without-libpsl --without-libgsasl --without-fish-functions-dir \ --disable-ares --disable-manual --disable-ldap --disable-ldaps --disable-static \ --without-gssapi --without-brotli # A few things we actually enable @@ -57,7 +57,15 @@ CURL_TLS_CONFIGURE_FLAGS := --with-mbedtls=$(build_prefix) endif CURL_CONFIGURE_FLAGS += $(CURL_TLS_CONFIGURE_FLAGS) -$(BUILDDIR)/curl-$(CURL_VER)/build-configured: $(SRCCACHE)/curl-$(CURL_VER)/source-extracted +$(SRCCACHE)/curl-$(CURL_VER)/curl-8.6.0-build.patch-applied: $(SRCCACHE)/curl-$(CURL_VER)/source-extracted + cd $(dir $@) && \ + patch -p1 -f < $(SRCDIR)/patches/curl-8.6.0-build.patch + echo 1 > $@ + +$(SRCCACHE)/curl-$(CURL_VER)/source-patched: $(SRCCACHE)/curl-$(CURL_VER)/curl-8.6.0-build.patch-applied + echo 1 > $@ + +$(BUILDDIR)/curl-$(CURL_VER)/build-configured: $(SRCCACHE)/curl-$(CURL_VER)/source-patched mkdir -p $(dir $@) cd $(dir $@) && \ $(dir $<)/configure $(CURL_CONFIGURE_FLAGS) \ diff --git a/deps/ittapi.mk b/deps/ittapi.mk index 505b7c8c28c64..b62b981a34ddb 100644 --- a/deps/ittapi.mk +++ b/deps/ittapi.mk @@ -14,7 +14,7 @@ $(BUILDDIR)/$(ITTAPI_SRC_DIR)/build-configured: $(SRCCACHE)/$(ITTAPI_SRC_DIR)/so echo 1 > $@ $(BUILDDIR)/$(ITTAPI_SRC_DIR)/build-compiled: $(BUILDDIR)/$(ITTAPI_SRC_DIR)/build-configured - $(CMAKE) --build $(dir $<) + $(MAKE) -C $(dir $<) echo 1 > $@ define ITTAPI_INSTALL diff --git a/deps/libgit2.mk b/deps/libgit2.mk index 162ad9fc513dd..b65ac022885a3 100644 --- a/deps/libgit2.mk +++ b/deps/libgit2.mk @@ -51,12 +51,12 @@ $(BUILDDIR)/$(LIBGIT2_SRC_DIR)/build-configured: $(LIBGIT2_SRC_PATH)/source-extr echo 1 > $@ $(BUILDDIR)/$(LIBGIT2_SRC_DIR)/build-compiled: $(BUILDDIR)/$(LIBGIT2_SRC_DIR)/build-configured - $(CMAKE) --build $(dir $<) + $(MAKE) -C $(dir $<) echo 1 > $@ $(BUILDDIR)/$(LIBGIT2_SRC_DIR)/build-checked: $(BUILDDIR)/$(LIBGIT2_SRC_DIR)/build-compiled ifeq ($(OS),$(BUILD_OS)) - $(CMAKE) --build $(dir $@) test + $(MAKE) -C $(dir $@) test endif echo 1 > $@ diff --git a/deps/libssh2.mk b/deps/libssh2.mk index 54d40dabbce1e..c293d8309d2bc 100644 --- a/deps/libssh2.mk +++ b/deps/libssh2.mk @@ -49,12 +49,12 @@ $(BUILDDIR)/$(LIBSSH2_SRC_DIR)/build-configured: $(LIBSSH2_SRC_PATH)/source-extr echo 1 > $@ $(BUILDDIR)/$(LIBSSH2_SRC_DIR)/build-compiled: $(BUILDDIR)/$(LIBSSH2_SRC_DIR)/build-configured - $(CMAKE) --build $(dir $<) + $(MAKE) -C $(dir $<) echo 1 > $@ $(BUILDDIR)/$(LIBSSH2_SRC_DIR)/build-checked: $(BUILDDIR)/$(LIBSSH2_SRC_DIR)/build-compiled ifeq ($(OS),$(BUILD_OS)) - $(CMAKE) --build $(dir $@) test + $(MAKE) -C $(dir $@) test endif echo 1 > $@ diff --git a/deps/libsuitesparse.mk b/deps/libsuitesparse.mk index c014686b1866e..85b2c23473a18 100644 --- a/deps/libsuitesparse.mk +++ b/deps/libsuitesparse.mk @@ -59,8 +59,8 @@ $(BUILDDIR)/SuiteSparse-$(LIBSUITESPARSE_VER)/build-compiled: | $(build_prefix)/ $(BUILDDIR)/SuiteSparse-$(LIBSUITESPARSE_VER)/build-compiled: $(BUILDDIR)/SuiteSparse-$(LIBSUITESPARSE_VER)/source-patched cd $(dir $<) && $(CMAKE) . $(LIBSUITESPARSE_CMAKE_FLAGS) - $(CMAKE) --build $(dir $<) - $(CMAKE) --install $(dir $<) + $(MAKE) -C $(dir $<) + $(MAKE) -C $(dir $<) install echo 1 > $@ ifeq ($(OS),WINNT) @@ -70,7 +70,7 @@ LIBSUITESPARSE_SHLIB_ENV:=LD_LIBRARY_PATH="$(build_shlibdir)" endif $(BUILDDIR)/SuiteSparse-$(LIBSUITESPARSE_VER)/build-checked: $(BUILDDIR)/SuiteSparse-$(LIBSUITESPARSE_VER)/build-compiled for PROJ in $(shell echo $(subst ;, ,$(LIBSUITESPARSE_PROJECTS))); do \ - $(LIBSUITESPARSE_SHLIB_ENV) $(CMAKE) --build $(dir $<)$${PROJ} default $(LIBSUITESPARSE_MFLAGS) || exit 1; \ + $(LIBSUITESPARSE_SHLIB_ENV) $(MAKE) -C $(dir $<)$${PROJ} default $(LIBSUITESPARSE_MFLAGS) || exit 1; \ done echo 1 > $@ @@ -113,9 +113,7 @@ uninstall-libsuitesparse: endef remove-libsuitesparse-gpl-lib: -ifeq ($(USE_GPL_LIBS),1) - @echo This build contains [GPL-2.0+] libs: libcholmod librbio libspqr libumfpack -else +ifeq ($(USE_GPL_LIBS),0) @echo Removing GPL libs... -rm -f $(build_bindir)/libcholmod* -rm -f $(build_bindir)/libklu_cholmod* diff --git a/deps/libsuitesparse.version b/deps/libsuitesparse.version index 3131908a4a298..6f841190cebc7 100644 --- a/deps/libsuitesparse.version +++ b/deps/libsuitesparse.version @@ -4,5 +4,5 @@ LIBSUITESPARSE_JLL_NAME := SuiteSparse ## source build -LIBSUITESPARSE_VER := 7.7.0 -LIBSUITESPARSE_SHA1=13806726cbf470914d012d132a85aea1aff9ee77 +LIBSUITESPARSE_VER := 7.8.0 +LIBSUITESPARSE_SHA1=58e6558408f6a51c08e35a5557d5e68cae32147e diff --git a/deps/libtracyclient.mk b/deps/libtracyclient.mk index 814f336584e98..92d6bee4caea6 100644 --- a/deps/libtracyclient.mk +++ b/deps/libtracyclient.mk @@ -55,7 +55,9 @@ $(LIBTRACYCLIENT_BUILDDIR)/build-configured: $(LIBTRACYCLIENT_BUILDDIR)/libTracy $(LIBTRACYCLIENT_BUILDDIR)/build-compiled: $(LIBTRACYCLIENT_BUILDDIR)/build-configured cd $(LIBTRACYCLIENT_BUILDDIR) && \ - $(CMAKE) --build . + $(if $(filter $(CMAKE_GENERATOR),make), \ + $(MAKE), \ + $(CMAKE) --build .) echo 1 > $@ $(eval $(call staged-install, \ diff --git a/deps/lld.version b/deps/lld.version index 431c1b7a75032..3ca9960164e27 100644 --- a/deps/lld.version +++ b/deps/lld.version @@ -2,4 +2,4 @@ ## jll artifact LLD_JLL_NAME := LLD -LLD_JLL_VER := 17.0.6+4 +LLD_JLL_VER := 18.1.7+2 diff --git a/deps/llvm-tools.version b/deps/llvm-tools.version index 3609c54ddc98f..1fcc8944dc769 100644 --- a/deps/llvm-tools.version +++ b/deps/llvm-tools.version @@ -3,5 +3,5 @@ ## jll artifact # LLVM_tools (downloads LLVM_jll to get things like `lit` and `opt`) LLVM_TOOLS_JLL_NAME := LLVM -LLVM_TOOLS_JLL_VER := 17.0.6+4 -LLVM_TOOLS_ASSERT_JLL_VER := 17.0.6+4 +LLVM_TOOLS_JLL_VER := 18.1.7+2 +LLVM_TOOLS_ASSERT_JLL_VER := 18.1.7+2 diff --git a/deps/llvm.mk b/deps/llvm.mk index 5e73c18f53289..08aff443dcff8 100644 --- a/deps/llvm.mk +++ b/deps/llvm.mk @@ -94,16 +94,15 @@ LLVM_LDFLAGS += $(BOLT_LDFLAGS) LLVM_CMAKE += -DLLVM_TARGETS_TO_BUILD:STRING="$(LLVM_TARGETS)" -DCMAKE_BUILD_TYPE="$(LLVM_CMAKE_BUILDTYPE)" LLVM_CMAKE += -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD:STRING="$(LLVM_EXPERIMENTAL_TARGETS)" LLVM_CMAKE += -DLLVM_ENABLE_LIBXML2=OFF -DLLVM_HOST_TRIPLE="$(or $(XC_HOST),$(BUILD_MACHINE))" -LLVM_CMAKE += -DLLVM_ENABLE_ZLIB=ON -DZLIB_LIBRARY="$(build_prefix)/lib" +LLVM_CMAKE += -DLLVM_ENABLE_ZLIB=FORCE_ON -DZLIB_ROOT="$(build_prefix)" LLVM_CMAKE += -DLLVM_ENABLE_ZSTD=OFF -LLVM_CMAKE += -DCOMPILER_RT_ENABLE_IOS=OFF -DCOMPILER_RT_ENABLE_WATCHOS=OFF -DCOMPILER_RT_ENABLE_TVOS=OFF ifeq ($(USE_POLLY_ACC),1) LLVM_CMAKE += -DPOLLY_ENABLE_GPGPU_CODEGEN=ON endif LLVM_CMAKE += -DLLVM_TOOLS_INSTALL_DIR=$(call rel_path,$(build_prefix),$(build_depsbindir)) LLVM_CMAKE += -DLLVM_UTILS_INSTALL_DIR=$(call rel_path,$(build_prefix),$(build_depsbindir)) LLVM_CMAKE += -DLLVM_INCLUDE_UTILS=ON -DLLVM_INSTALL_UTILS=ON -LLVM_CMAKE += -DLLVM_BINDINGS_LIST="" -DLLVM_ENABLE_BINDINGS=OFF -DLLVM_INCLUDE_DOCS=Off -DLLVM_ENABLE_TERMINFO=Off -DHAVE_HISTEDIT_H=Off -DHAVE_LIBEDIT=Off +LLVM_CMAKE += -DLLVM_BINDINGS_LIST="" -DLLVM_ENABLE_BINDINGS=OFF -DLLVM_INCLUDE_DOCS=Off -DLLVM_ENABLE_TERMINFO=Off -DHAVE_LIBEDIT=Off ifeq ($(LLVM_ASSERTIONS), 1) LLVM_CMAKE += -DLLVM_ENABLE_ASSERTIONS:BOOL=ON endif # LLVM_ASSERTIONS @@ -270,7 +269,9 @@ $(LLVM_BUILDDIR_withtype)/build-configured: $(SRCCACHE)/$(LLVM_SRC_DIR)/source-e $(LLVM_BUILDDIR_withtype)/build-compiled: $(LLVM_BUILDDIR_withtype)/build-configured cd $(LLVM_BUILDDIR_withtype) && \ - $(CMAKE) --build . + $(if $(filter $(CMAKE_GENERATOR),make), \ + $(MAKE), \ + $(CMAKE) --build .) echo 1 > $@ $(LLVM_BUILDDIR_withtype)/build-checked: $(LLVM_BUILDDIR_withtype)/build-compiled diff --git a/deps/llvm.version b/deps/llvm.version index c02a52008fe25..8e4180ef5a277 100644 --- a/deps/llvm.version +++ b/deps/llvm.version @@ -2,14 +2,14 @@ ## jll artifact LLVM_JLL_NAME := libLLVM -LLVM_ASSERT_JLL_VER := 17.0.6+4 +LLVM_ASSERT_JLL_VER := 18.1.7+2 ## source build # Version number of LLVM -LLVM_VER := 17.0.6 +LLVM_VER := 18.1.7 # Git branch name in `LLVM_GIT_URL` repository -LLVM_BRANCH=julia-17.0.6-4 +LLVM_BRANCH=julia-18.1.7-2 # Git ref in `LLVM_GIT_URL` repository -LLVM_SHA1=julia-17.0.6-4 +LLVM_SHA1=julia-18.1.7-2 ## Following options are used to automatically fetch patchset from Julia's fork. This is ## useful if you want to build an external LLVM while still applying Julia's patches. @@ -18,6 +18,6 @@ LLVM_APPLY_JULIA_PATCHES := 0 # GitHub repository to use for fetching the Julia patches to apply to LLVM source code. LLVM_JULIA_DIFF_GITHUB_REPO := https://github.com/llvm/llvm-project # Base GitHub ref for generating the diff. -LLVM_BASE_REF := llvm:llvmorg-17.0.6 +LLVM_BASE_REF := llvm:llvmorg-18.1.7 # Julia fork's GitHub ref for generating the diff. -LLVM_JULIA_REF := JuliaLang:julia-17.0.6-4 +LLVM_JULIA_REF := JuliaLang:julia-18.1.7-2 diff --git a/deps/mbedtls.mk b/deps/mbedtls.mk index 79f6dadf1d383..39cf817d70658 100644 --- a/deps/mbedtls.mk +++ b/deps/mbedtls.mk @@ -39,12 +39,12 @@ $(BUILDDIR)/$(MBEDTLS_SRC)/build-configured: $(SRCCACHE)/$(MBEDTLS_SRC)/source-e echo 1 > $@ $(BUILDDIR)/$(MBEDTLS_SRC)/build-compiled: $(BUILDDIR)/$(MBEDTLS_SRC)/build-configured - $(CMAKE) --build $(dir $<) + $(MAKE) -C $(dir $<) echo 1 > $@ $(BUILDDIR)/$(MBEDTLS_SRC)/build-checked: $(BUILDDIR)/$(MBEDTLS_SRC)/build-compiled ifeq ($(OS),$(BUILD_OS)) - $(CMAKE) --build $(dir $@) test + $(MAKE) -C $(dir $@) test endif echo 1 > $@ diff --git a/deps/openblas.version b/deps/openblas.version index 527764e3f8603..09dcdc45af1ef 100644 --- a/deps/openblas.version +++ b/deps/openblas.version @@ -3,9 +3,9 @@ OPENBLAS_JLL_NAME := OpenBLAS ## source build -OPENBLAS_VER := 0.3.27 -OPENBLAS_BRANCH=v0.3.27 -OPENBLAS_SHA1=6c77e5e314474773a7749357b153caba4ec3817d +OPENBLAS_VER := 0.3.28 +OPENBLAS_BRANCH=v0.3.28 +OPENBLAS_SHA1=5ef8b1964658f9cb6a6324a06f6a1a022609b0c5 # LAPACK, source-only LAPACK_VER := 3.9.0 diff --git a/deps/patches/curl-8.6.0-build.patch b/deps/patches/curl-8.6.0-build.patch new file mode 100644 index 0000000000000..827b02808d505 --- /dev/null +++ b/deps/patches/curl-8.6.0-build.patch @@ -0,0 +1,23 @@ +From 5cc2b016c36aaf5a08e2feb7c068fca5bb0a8052 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Mon, 5 Feb 2024 15:22:08 +0100 +Subject: [PATCH] md4: include strdup.h for the memdup proto + +Reported-by: Erik Schnetter +Fixes #12849 +Closes #12863 +--- + lib/md4.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/lib/md4.c b/lib/md4.c +index 067c211e420afd..58dd1166cf924f 100644 +--- a/lib/md4.c ++++ b/lib/md4.c +@@ -28,6 +28,7 @@ + + #include + ++#include "strdup.h" + #include "curl_md4.h" + #include "warnless.h" diff --git a/deps/patches/libunwind-disable-initial-exec-tls.patch b/deps/patches/libunwind-disable-initial-exec-tls.patch new file mode 100644 index 0000000000000..c6718ac2db98f --- /dev/null +++ b/deps/patches/libunwind-disable-initial-exec-tls.patch @@ -0,0 +1,44 @@ +diff --git a/include/libunwind-common.h.in b/include/libunwind-common.h.in +index 893fdd69..80ab9648 100644 +--- a/include/libunwind-common.h.in ++++ b/include/libunwind-common.h.in +@@ -340,5 +340,6 @@ extern int unw_get_elf_filename_by_ip (unw_addr_space_t, unw_word_t, char *, + extern const char *unw_strerror (int); + extern int unw_backtrace (void **, int); + extern int unw_backtrace2 (void **, int, unw_context_t*, int); ++extern int unw_ensure_tls (void); + + extern unw_addr_space_t unw_local_addr_space; +diff --git a/src/dwarf/Gparser.c b/src/dwarf/Gparser.c +index 7a5d7e1f..8453ffb0 100644 +--- a/src/dwarf/Gparser.c ++++ b/src/dwarf/Gparser.c +@@ -623,7 +623,7 @@ get_rs_cache (unw_addr_space_t as, intrmask_t *saved_maskp) + #if defined(HAVE___CACHE_PER_THREAD) && HAVE___CACHE_PER_THREAD + if (likely (caching == UNW_CACHE_PER_THREAD)) + { +- static _Thread_local struct dwarf_rs_cache tls_cache __attribute__((tls_model("initial-exec"))); ++ static _Thread_local struct dwarf_rs_cache tls_cache; + Debug (16, "using TLS cache\n"); + cache = &tls_cache; + } +diff --git a/src/mi/init.c b/src/mi/init.c +index e4431eeb..07cae852 100644 +--- a/src/mi/init.c ++++ b/src/mi/init.c +@@ -82,3 +82,15 @@ mi_init (void) + unw_init_page_size(); + assert(sizeof(struct cursor) <= sizeof(unw_cursor_t)); + } ++ ++int ++unw_ensure_tls (void) ++{ ++#if defined(HAVE___CACHE_PER_THREAD) && HAVE___CACHE_PER_THREAD ++ static _Thread_local int alloc_trigger; ++ alloc_trigger = 1; ++ return alloc_trigger; ++#else ++ return 0; ++#endif ++} diff --git a/deps/terminfo.mk b/deps/terminfo.mk new file mode 100644 index 0000000000000..63194f786f566 --- /dev/null +++ b/deps/terminfo.mk @@ -0,0 +1,43 @@ +## TERMINFO-DB ## +include $(SRCDIR)/terminfo.version + +$(SRCCACHE)/TermInfoDB-v$(TERMINFO_VER).any.tar.gz: | $(SRCCACHE) + $(JLDOWNLOAD) $@ https://github.com/JuliaBinaryWrappers/TermInfoDB_jll.jl/releases/download/$(TERMINFO_TAG)/TermInfoDB.v$(TERMINFO_VER).any.tar.gz + touch -c $@ + +$(BUILDDIR)/TermInfoDB-v$(TERMINFO_VER)/source-extracted: $(SRCCACHE)/TermInfoDB-v$(TERMINFO_VER).any.tar.gz + $(JLCHECKSUM) $< + rm -rf $(dir $@) + mkdir -p $(dir $@) + $(TAR) -C $(dir $@) --strip-components 1 -xf $< + echo 1 > $@ + +checksum-terminfo: $(SRCCACHE)/TermInfoDB-v$(TERMINFO_VER).any.tar.gz + $(JLCHECKSUM) $< + +$(BUILDDIR)/TermInfoDB-v$(TERMINFO_VER)/build-compiled: $(BUILDDIR)/TermInfoDB-v$(TERMINFO_VER)/source-extracted + echo 1 > $@ + +$(BUILDDIR)/TermInfoDB-v$(TERMINFO_VER)/build-checked: $(BUILDDIR)/TermInfoDB-v$(TERMINFO_VER)/build-compiled + echo 1 > $@ + +define TERMINFO_INSTALL + mkdir -p $2/$$(build_datarootdir) + cp -R $1/terminfo $2/$$(build_datarootdir) +endef +$(eval $(call staged-install, \ + terminfo,TermInfoDB-v$(TERMINFO_VER), \ + TERMINFO_INSTALL,,,,)) + +clean-terminfo: + -rm -f $(BUILDDIR)/TermInfoDB-v$(TERMINFO_VER)/build-compiled + +distclean-terminfo: + rm -rf $(SRCCACHE)/TermInfoDB*.tar.gz $(SRCCACHE)/TermInfoDB-v$(TERMINFO_VER) $(BUILDDIR)/TermInfoDB-v$(TERMINFO_VER) + +get-terminfo: $(SRCCACHE)/TermInfoDB-v$(TERMINFO_VER).any.tar.gz +extract-terminfo: $(BUILDDIR)/TermInfoDB-v$(TERMINFO_VER)/source-extracted +configure-terminfo: extract-terminfo +compile-terminfo: $(BUILDDIR)/TermInfoDB-v$(TERMINFO_VER)/build-compiled +fastcheck-terminfo: check-terminfo +check-terminfo: $(BUILDDIR)/TermInfoDB-v$(TERMINFO_VER)/build-checked diff --git a/deps/terminfo.version b/deps/terminfo.version new file mode 100644 index 0000000000000..b7c020b830517 --- /dev/null +++ b/deps/terminfo.version @@ -0,0 +1,3 @@ +# -*- makefile -*- +TERMINFO_VER := 2023.12.9 +TERMINFO_TAG := TermInfoDB-v$(TERMINFO_VER)+0 diff --git a/deps/unwind.mk b/deps/unwind.mk index 0bfaca574f5e6..079e4d69b04a3 100644 --- a/deps/unwind.mk +++ b/deps/unwind.mk @@ -38,13 +38,17 @@ $(SRCCACHE)/libunwind-$(UNWIND_VER)/libunwind-aarch64-inline-asm.patch-applied: cd $(SRCCACHE)/libunwind-$(UNWIND_VER) && patch -p1 -f -u -l < $(SRCDIR)/patches/libunwind-aarch64-inline-asm.patch echo 1 > $@ +$(SRCCACHE)/libunwind-$(UNWIND_VER)/libunwind-disable-initial-exec-tls.patch-applied: $(SRCCACHE)/libunwind-$(UNWIND_VER)/libunwind-aarch64-inline-asm.patch-applied + cd $(SRCCACHE)/libunwind-$(UNWIND_VER) && patch -p1 -f -u -l < $(SRCDIR)/patches/libunwind-disable-initial-exec-tls.patch + echo 1 > $@ + # note minidebuginfo requires liblzma, which we do not have a source build for # (it will be enabled in BinaryBuilder-based downloads however) # since https://github.com/JuliaPackaging/Yggdrasil/commit/0149e021be9badcb331007c62442a4f554f3003c -$(BUILDDIR)/libunwind-$(UNWIND_VER)/build-configured: $(SRCCACHE)/libunwind-$(UNWIND_VER)/source-extracted $(SRCCACHE)/libunwind-$(UNWIND_VER)/libunwind-aarch64-inline-asm.patch-applied +$(BUILDDIR)/libunwind-$(UNWIND_VER)/build-configured: $(SRCCACHE)/libunwind-$(UNWIND_VER)/source-extracted $(SRCCACHE)/libunwind-$(UNWIND_VER)/libunwind-disable-initial-exec-tls.patch-applied mkdir -p $(dir $@) cd $(dir $@) && \ - $(dir $<)/configure $(CONFIGURE_COMMON) CPPFLAGS="$(CPPFLAGS) $(LIBUNWIND_CPPFLAGS)" CFLAGS="$(CFLAGS) $(LIBUNWIND_CFLAGS)" --enable-shared --disable-minidebuginfo --disable-tests --enable-zlibdebuginfo --disable-conservative-checks + $(dir $<)/configure $(CONFIGURE_COMMON) CPPFLAGS="$(CPPFLAGS) $(LIBUNWIND_CPPFLAGS)" CFLAGS="$(CFLAGS) $(LIBUNWIND_CFLAGS)" --enable-shared --disable-minidebuginfo --disable-tests --enable-zlibdebuginfo --disable-conservative-checks --enable-per-thread-cache echo 1 > $@ $(BUILDDIR)/libunwind-$(UNWIND_VER)/build-compiled: $(BUILDDIR)/libunwind-$(UNWIND_VER)/build-configured @@ -121,7 +125,7 @@ $(BUILDDIR)/llvmunwind-$(LLVMUNWIND_VER)/build-configured: $(SRCCACHE)/llvmunwin echo 1 > $@ $(BUILDDIR)/llvmunwind-$(LLVMUNWIND_VER)/build-compiled: $(BUILDDIR)/llvmunwind-$(LLVMUNWIND_VER)/build-configured - $(CMAKE) --build $(dir $<) + $(MAKE) -C $(dir $<) echo 1 > $@ $(eval $(call staged-install, \ diff --git a/deps/zlib.mk b/deps/zlib.mk index 95168b115ef31..5548a0791f4d2 100644 --- a/deps/zlib.mk +++ b/deps/zlib.mk @@ -14,7 +14,7 @@ $(BUILDDIR)/$(ZLIB_SRC_DIR)/build-configured: $(SRCCACHE)/$(ZLIB_SRC_DIR)/source echo 1 > $@ $(BUILDDIR)/$(ZLIB_SRC_DIR)/build-compiled: $(BUILDDIR)/$(ZLIB_SRC_DIR)/build-configured - $(CMAKE) --build $(dir $<) + $(MAKE) -C $(dir $<) $(MAKE_COMMON) echo 1 > $@ $(eval $(call staged-install, \ diff --git a/doc/src/base/arrays.md b/doc/src/base/arrays.md index ccfb23715c476..66fe5c78f1ee6 100644 --- a/doc/src/base/arrays.md +++ b/doc/src/base/arrays.md @@ -138,6 +138,7 @@ Base.parentindices Base.selectdim Base.reinterpret Base.reshape +Base.insertdims Base.dropdims Base.vec Base.SubArray diff --git a/doc/src/base/base.md b/doc/src/base/base.md index 946f917682814..1a8cd29f91066 100644 --- a/doc/src/base/base.md +++ b/doc/src/base/base.md @@ -281,6 +281,7 @@ Base.:(|>) Base.:(∘) Base.ComposedFunction Base.splat +Base.Fix Base.Fix1 Base.Fix2 ``` diff --git a/doc/src/base/parallel.md b/doc/src/base/parallel.md index 58ec078a8e0cf..9f24db176b538 100644 --- a/doc/src/base/parallel.md +++ b/doc/src/base/parallel.md @@ -138,7 +138,7 @@ end ev = OneWayEvent() @sync begin - @async begin + Threads.@spawn begin wait(ev) println("done") end diff --git a/doc/src/base/strings.md b/doc/src/base/strings.md index ef470be6b55cc..b7d16ffc7d487 100644 --- a/doc/src/base/strings.md +++ b/doc/src/base/strings.md @@ -48,6 +48,9 @@ Base.:(==)(::AbstractString, ::AbstractString) Base.cmp(::AbstractString, ::AbstractString) Base.lpad Base.rpad +Base.ltruncate +Base.rtruncate +Base.ctruncate Base.findfirst(::AbstractString, ::AbstractString) Base.findnext(::AbstractString, ::AbstractString, ::Integer) Base.findnext(::AbstractChar, ::AbstractString, ::Integer) diff --git a/doc/src/devdocs/object.md b/doc/src/devdocs/object.md index a2f72d623ab21..8134132d6ee75 100644 --- a/doc/src/devdocs/object.md +++ b/doc/src/devdocs/object.md @@ -92,7 +92,7 @@ The corresponding global `jl_datatype_t` objects are created by [`jl_init_types` The garbage collector uses several bits from the metadata portion of the `jl_typetag_t` to track each object in the system. Further details about this algorithm can be found in the comments of -the [garbage collector implementation in `gc.c`](https://github.com/JuliaLang/julia/blob/master/src/gc.c). +the [garbage collector implementation in `gc-stock.c`](https://github.com/JuliaLang/julia/blob/master/src/gc-stock.c). ## Object allocation @@ -179,7 +179,7 @@ jl_value_t *newstruct(jl_value_t *type); jl_value_t *newobj(jl_value_t *type, size_t nfields); ``` -And at the lowest level, memory is getting allocated by a call to the garbage collector (in `gc.c`), +And at the lowest level, memory is getting allocated by a call to the garbage collector (in `gc-stock.c`), then tagged with its type: ```c diff --git a/doc/src/devdocs/probes.md b/doc/src/devdocs/probes.md index 5a1af0d897bc6..a0e072c0b1ae3 100644 --- a/doc/src/devdocs/probes.md +++ b/doc/src/devdocs/probes.md @@ -206,7 +206,7 @@ Now we can start `bpftrace` and have it monitor `rt__new__task` for *only* this And if we spawn a single task: -`@async 1+1` +`Threads.@spawn 1+1` we see this task being created: @@ -215,8 +215,8 @@ we see this task being created: However, if we spawn a bunch of tasks from that newly-spawned task: ```julia -@async for i in 1:10 - @async 1+1 +Threads.@spawn for i in 1:10 + Threads.@spawn 1+1 end ``` diff --git a/doc/src/manual/asynchronous-programming.md b/doc/src/manual/asynchronous-programming.md index 15db6eda5f807..d1d095c48b2ff 100644 --- a/doc/src/manual/asynchronous-programming.md +++ b/doc/src/manual/asynchronous-programming.md @@ -64,8 +64,8 @@ the next input prompt appears. That is because the REPL is waiting for `t` to finish before proceeding. It is common to want to create a task and schedule it right away, so the -macro [`@async`](@ref) is provided for that purpose --- `@async x` is -equivalent to `schedule(@task x)`. +macro [`Threads.@spawn`](@ref) is provided for that purpose --- `Threads.@spawn x` is +equivalent to `task = @task x; task.sticky = false; schedule(task)`. ## Communicating with Channels @@ -186,7 +186,7 @@ A channel can be visualized as a pipe, i.e., it has a write end and a read end : # we can schedule `n` instances of `foo` to be active concurrently. for _ in 1:n - errormonitor(@async foo()) + errormonitor(Threads.@spawn foo()) end ``` * Channels are created via the `Channel{T}(sz)` constructor. The channel will only hold objects @@ -264,10 +264,10 @@ julia> function make_jobs(n) julia> n = 12; -julia> errormonitor(@async make_jobs(n)); # feed the jobs channel with "n" jobs +julia> errormonitor(Threads.@spawn make_jobs(n)); # feed the jobs channel with "n" jobs julia> for i in 1:4 # start 4 tasks to process requests in parallel - errormonitor(@async do_work()) + errormonitor(Threads.@spawn do_work()) end julia> @elapsed while n > 0 # print out results diff --git a/doc/src/manual/distributed-computing.md b/doc/src/manual/distributed-computing.md index d325239fc9e2d..f60dfb7004ada 100644 --- a/doc/src/manual/distributed-computing.md +++ b/doc/src/manual/distributed-computing.md @@ -123,7 +123,7 @@ An important thing to remember is that, once fetched, a [`Future`](@ref Distribu locally. Further [`fetch`](@ref) calls do not entail a network hop. Once all referencing [`Future`](@ref Distributed.Future)s have fetched, the remote stored value is deleted. -[`@async`](@ref) is similar to [`@spawnat`](@ref), but only runs tasks on the local process. We +[`Threads.@spawn`](@ref) is similar to [`@spawnat`](@ref), but only runs tasks on the local process. We use it to create a "feeder" task for each process. Each task picks the next index that needs to be computed, then waits for its process to finish, then repeats until we run out of indices. Note that the feeder tasks do not begin to execute until the main task reaches the end of the [`@sync`](@ref) @@ -657,7 +657,7 @@ julia> function make_jobs(n) julia> n = 12; -julia> errormonitor(@async make_jobs(n)); # feed the jobs channel with "n" jobs +julia> errormonitor(Threads.@spawn make_jobs(n)); # feed the jobs channel with "n" jobs julia> for p in workers() # start tasks on the workers to process requests in parallel remote_do(do_work, p, jobs, results) @@ -896,7 +896,7 @@ conflicts. For example: ```julia @sync begin for p in procs(S) - @async begin + Threads.@spawn begin remotecall_wait(fill!, p, S, p) end end @@ -978,7 +978,7 @@ and one that delegates in chunks: julia> function advection_shared!(q, u) @sync begin for p in procs(q) - @async remotecall_wait(advection_shared_chunk!, p, q, u) + Threads.@spawn remotecall_wait(advection_shared_chunk!, p, q, u) end end q diff --git a/doc/src/manual/faq.md b/doc/src/manual/faq.md index 8984e1d15ddd3..2673ca7532acf 100644 --- a/doc/src/manual/faq.md +++ b/doc/src/manual/faq.md @@ -943,7 +943,7 @@ Consider the printed output from the following: ```jldoctest julia> @sync for i in 1:3 - @async write(stdout, string(i), " Foo ", " Bar ") + Threads.@spawn write(stdout, string(i), " Foo ", " Bar ") end 123 Foo Foo Foo Bar Bar Bar ``` @@ -956,7 +956,7 @@ in the above example results in: ```jldoctest julia> @sync for i in 1:3 - @async println(stdout, string(i), " Foo ", " Bar ") + Threads.@spawn println(stdout, string(i), " Foo ", " Bar ") end 1 Foo Bar 2 Foo Bar @@ -969,7 +969,7 @@ You can lock your writes with a `ReentrantLock` like this: julia> l = ReentrantLock(); julia> @sync for i in 1:3 - @async begin + Threads.@spawn begin lock(l) try write(stdout, string(i), " Foo ", " Bar ") diff --git a/doc/src/manual/methods.md b/doc/src/manual/methods.md index d45644bf55842..6be44dcf4fa13 100644 --- a/doc/src/manual/methods.md +++ b/doc/src/manual/methods.md @@ -614,7 +614,7 @@ Start some other operations that use `f(x)`: julia> g(x) = f(x) g (generic function with 1 method) -julia> t = @async f(wait()); yield(); +julia> t = Threads.@spawn f(wait()); yield(); ``` Now we add some new methods to `f(x)`: @@ -639,7 +639,7 @@ julia> g(1) julia> fetch(schedule(t, 1)) "original definition" -julia> t = @async f(wait()); yield(); +julia> t = Threads.@spawn f(wait()); yield(); julia> fetch(schedule(t, 1)) "definition for Int" diff --git a/doc/src/manual/networking-and-streams.md b/doc/src/manual/networking-and-streams.md index 45bf60a7944d2..35ba7fdf16601 100644 --- a/doc/src/manual/networking-and-streams.md +++ b/doc/src/manual/networking-and-streams.md @@ -233,7 +233,7 @@ Let's first create a simple server: ```julia-repl julia> using Sockets -julia> errormonitor(@async begin +julia> errormonitor(Threads.@spawn begin server = listen(2000) while true sock = accept(server) @@ -305,11 +305,11 @@ printed the message and waited for the next client. Reading and writing works in To see this, consider the following simple echo server: ```julia-repl -julia> errormonitor(@async begin +julia> errormonitor(Threads.@spawn begin server = listen(2001) while true sock = accept(server) - @async while isopen(sock) + Threads.@spawn while isopen(sock) write(sock, readline(sock, keep=true)) end end @@ -319,7 +319,7 @@ Task (runnable) @0x00007fd31dc12e60 julia> clientside = connect(2001) TCPSocket(RawFD(28) open, 0 bytes waiting) -julia> errormonitor(@async while isopen(clientside) +julia> errormonitor(Threads.@spawn while isopen(clientside) write(stdout, readline(clientside, keep=true)) end) Task (runnable) @0x00007fd31dc11870 @@ -357,10 +357,10 @@ ip"74.125.226.225" All I/O operations exposed by [`Base.read`](@ref) and [`Base.write`](@ref) can be performed asynchronously through the use of [coroutines](@ref man-tasks). You can create a new coroutine to -read from or write to a stream using the [`@async`](@ref) macro: +read from or write to a stream using the [`Threads.@spawn`](@ref) macro: ```julia-repl -julia> task = @async open("foo.txt", "w") do io +julia> task = Threads.@spawn open("foo.txt", "w") do io write(io, "Hello, World!") end; @@ -379,7 +379,7 @@ your program to block until all of the coroutines it wraps around have exited: julia> using Sockets julia> @sync for hostname in ("google.com", "github.com", "julialang.org") - @async begin + Threads.@spawn begin conn = connect(hostname, 80) write(conn, "GET / HTTP/1.1\r\nHost:$(hostname)\r\n\r\n") readline(conn, keep=true) diff --git a/doc/src/manual/performance-tips.md b/doc/src/manual/performance-tips.md index 5c10652eb99cb..38e27476f0af8 100644 --- a/doc/src/manual/performance-tips.md +++ b/doc/src/manual/performance-tips.md @@ -1723,7 +1723,7 @@ using Distributed responses = Vector{Any}(undef, nworkers()) @sync begin for (idx, pid) in enumerate(workers()) - @async responses[idx] = remotecall_fetch(foo, pid, args...) + Threads.@spawn responses[idx] = remotecall_fetch(foo, pid, args...) end end ``` diff --git a/doc/src/manual/running-external-programs.md b/doc/src/manual/running-external-programs.md index 4a9803337990b..1f9f3129ca16b 100644 --- a/doc/src/manual/running-external-programs.md +++ b/doc/src/manual/running-external-programs.md @@ -332,8 +332,8 @@ will attempt to store the data in the kernel's buffers while waiting for a reade Another common solution is to separate the reader and writer of the pipeline into separate [`Task`](@ref)s: ```julia -writer = @async write(process, "data") -reader = @async do_compute(read(process, String)) +writer = Threads.@spawn write(process, "data") +reader = Threads.@spawn do_compute(read(process, String)) wait(writer) fetch(reader) ``` diff --git a/doc/src/manual/variables-and-scoping.md b/doc/src/manual/variables-and-scoping.md index 85a83120dc517..de97ff296e37e 100644 --- a/doc/src/manual/variables-and-scoping.md +++ b/doc/src/manual/variables-and-scoping.md @@ -755,28 +755,7 @@ julia> const z = 100 julia> z = 100 100 ``` -The last rule applies to immutable objects even if the variable binding would change, e.g.: -```julia-repl -julia> const s1 = "1" -"1" - -julia> s2 = "1" -"1" - -julia> pointer.([s1, s2], 1) -2-element Array{Ptr{UInt8},1}: - Ptr{UInt8} @0x00000000132c9638 - Ptr{UInt8} @0x0000000013dd3d18 - -julia> s1 = s2 -"1" - -julia> pointer.([s1, s2], 1) -2-element Array{Ptr{UInt8},1}: - Ptr{UInt8} @0x0000000013dd3d18 - Ptr{UInt8} @0x0000000013dd3d18 -``` -However, for mutable objects the warning is printed as expected: +* if an assignment would change the mutable object to which the variable points (regardless of whether those two objects are deeply equal), a warning is printed: ```jldoctest julia> const a = [1] 1-element Vector{Int64}: diff --git a/src/Makefile b/src/Makefile index 4da44a8cc8d81..6f78f4a8b6aa1 100644 --- a/src/Makefile +++ b/src/Makefile @@ -44,7 +44,7 @@ SRCS := \ jltypes gf typemap smallintset ast builtins module interpreter symbol \ dlload sys init task array genericmemory staticdata toplevel jl_uv datatype \ simplevector runtime_intrinsics precompile jloptions mtarraylist \ - threading scheduler stackwalk gc gc-debug gc-pages gc-stacks gc-alloc-profiler gc-page-profiler method \ + threading scheduler stackwalk gc-common gc-stock gc-debug gc-pages gc-stacks gc-alloc-profiler gc-page-profiler method \ jlapi signal-handling safepoint timing subtype rtutils gc-heap-snapshot \ crc32c APInt-C processor ircode opaque_closure codegen-stubs coverage runtime_ccall engine @@ -103,7 +103,7 @@ ifeq ($(USE_SYSTEM_LIBUV),0) UV_HEADERS += uv.h UV_HEADERS += uv/*.h endif -PUBLIC_HEADERS := $(BUILDDIR)/julia_version.h $(wildcard $(SRCDIR)/support/*.h) $(addprefix $(SRCDIR)/,work-stealing-queue.h gc-tls.h julia.h julia_assert.h julia_threads.h julia_fasttls.h julia_locks.h julia_atomics.h jloptions.h) +PUBLIC_HEADERS := $(BUILDDIR)/julia_version.h $(wildcard $(SRCDIR)/support/*.h) $(addprefix $(SRCDIR)/,work-stealing-queue.h gc-interface.h gc-tls.h julia.h julia_assert.h julia_threads.h julia_fasttls.h julia_locks.h julia_atomics.h jloptions.h) ifeq ($(OS),WINNT) PUBLIC_HEADERS += $(addprefix $(SRCDIR)/,win32_ucontext.h) endif @@ -316,11 +316,11 @@ $(BUILDDIR)/codegen.o $(BUILDDIR)/codegen.dbg.obj: $(addprefix $(SRCDIR)/,\ $(BUILDDIR)/datatype.o $(BUILDDIR)/datatype.dbg.obj: $(SRCDIR)/support/htable.h $(SRCDIR)/support/htable.inc $(BUILDDIR)/debuginfo.o $(BUILDDIR)/debuginfo.dbg.obj: $(addprefix $(SRCDIR)/,debuginfo.h processor.h jitlayers.h debug-registry.h) $(BUILDDIR)/disasm.o $(BUILDDIR)/disasm.dbg.obj: $(SRCDIR)/debuginfo.h $(SRCDIR)/processor.h -$(BUILDDIR)/gc-debug.o $(BUILDDIR)/gc-debug.dbg.obj: $(SRCDIR)/gc.h -$(BUILDDIR)/gc-pages.o $(BUILDDIR)/gc-pages.dbg.obj: $(SRCDIR)/gc.h -$(BUILDDIR)/gc.o $(BUILDDIR)/gc.dbg.obj: $(SRCDIR)/gc.h $(SRCDIR)/gc-heap-snapshot.h $(SRCDIR)/gc-alloc-profiler.h $(SRCDIR)/gc-page-profiler.h -$(BUILDDIR)/gc-heap-snapshot.o $(BUILDDIR)/gc-heap-snapshot.dbg.obj: $(SRCDIR)/gc.h $(SRCDIR)/gc-heap-snapshot.h -$(BUILDDIR)/gc-alloc-profiler.o $(BUILDDIR)/gc-alloc-profiler.dbg.obj: $(SRCDIR)/gc.h $(SRCDIR)/gc-alloc-profiler.h +$(BUILDDIR)/gc-debug.o $(BUILDDIR)/gc-debug.dbg.obj: $(SRCDIR)/gc-common.h $(SRCDIR)/gc-stock.h +$(BUILDDIR)/gc-pages.o $(BUILDDIR)/gc-pages.dbg.obj: $(SRCDIR)/gc-common.h $(SRCDIR)/gc-stock.h +$(BUILDDIR)/gc-stock.o $(BUILDDIR)/gc.dbg.obj: $(SRCDIR)/gc-common.h $(SRCDIR)/gc-stock.h $(SRCDIR)/gc-heap-snapshot.h $(SRCDIR)/gc-alloc-profiler.h $(SRCDIR)/gc-page-profiler.h +$(BUILDDIR)/gc-heap-snapshot.o $(BUILDDIR)/gc-heap-snapshot.dbg.obj: $(SRCDIR)/gc-heap-snapshot.h +$(BUILDDIR)/gc-alloc-profiler.o $(BUILDDIR)/gc-alloc-profiler.dbg.obj: $(SRCDIR)/gc-alloc-profiler.h $(BUILDDIR)/gc-page-profiler.o $(BUILDDIR)/gc-page-profiler.dbg.obj: $(SRCDIR)/gc-page-profiler.h $(BUILDDIR)/init.o $(BUILDDIR)/init.dbg.obj: $(SRCDIR)/builtin_proto.h $(BUILDDIR)/interpreter.o $(BUILDDIR)/interpreter.dbg.obj: $(SRCDIR)/builtin_proto.h @@ -331,10 +331,10 @@ $(BUILDDIR)/llvm-alloc-helpers.o $(BUILDDIR)/llvm-alloc-helpers.dbg.obj: $(SRCDI $(BUILDDIR)/llvm-alloc-opt.o $(BUILDDIR)/llvm-alloc-opt.dbg.obj: $(SRCDIR)/llvm-codegen-shared.h $(SRCDIR)/llvm-pass-helpers.h $(SRCDIR)/llvm-alloc-helpers.h $(BUILDDIR)/llvm-cpufeatures.o $(BUILDDIR)/llvm-cpufeatures.dbg.obj: $(SRCDIR)/jitlayers.h $(BUILDDIR)/llvm-demote-float16.o $(BUILDDIR)/llvm-demote-float16.dbg.obj: $(SRCDIR)/jitlayers.h -$(BUILDDIR)/llvm-final-gc-lowering.o $(BUILDDIR)/llvm-final-gc-lowering.dbg.obj: $(SRCDIR)/llvm-pass-helpers.h $(SRCDIR)/llvm-codegen-shared.h +$(BUILDDIR)/llvm-final-gc-lowering.o $(BUILDDIR)/llvm-final-gc-lowering.dbg.obj: $(SRCDIR)/llvm-gc-interface-passes.h $(BUILDDIR)/llvm-gc-invariant-verifier.o $(BUILDDIR)/llvm-gc-invariant-verifier.dbg.obj: $(SRCDIR)/llvm-codegen-shared.h $(BUILDDIR)/llvm-julia-licm.o $(BUILDDIR)/llvm-julia-licm.dbg.obj: $(SRCDIR)/llvm-codegen-shared.h $(SRCDIR)/llvm-alloc-helpers.h $(SRCDIR)/llvm-pass-helpers.h -$(BUILDDIR)/llvm-late-gc-lowering.o $(BUILDDIR)/llvm-late-gc-lowering.dbg.obj: $(SRCDIR)/llvm-pass-helpers.h $(SRCDIR)/llvm-codegen-shared.h +$(BUILDDIR)/llvm-late-gc-lowering.o $(BUILDDIR)/llvm-late-gc-lowering.dbg.obj: $(SRCDIR)/llvm-gc-interface-passes.h $(BUILDDIR)/llvm-lower-handlers.o $(BUILDDIR)/llvm-lower-handlers.dbg.obj: $(SRCDIR)/llvm-codegen-shared.h $(BUILDDIR)/llvm-multiversioning.o $(BUILDDIR)/llvm-multiversioning.dbg.obj: $(SRCDIR)/llvm-codegen-shared.h $(SRCDIR)/processor.h $(BUILDDIR)/llvm-pass-helpers.o $(BUILDDIR)/llvm-pass-helpers.dbg.obj: $(SRCDIR)/llvm-pass-helpers.h $(SRCDIR)/llvm-codegen-shared.h @@ -348,7 +348,7 @@ $(BUILDDIR)/toplevel.o $(BUILDDIR)/toplevel.dbg.obj: $(SRCDIR)/builtin_proto.h $(BUILDDIR)/ircode.o $(BUILDDIR)/ircode.dbg.obj: $(SRCDIR)/serialize.h $(SRCDIR)/common_symbols1.inc $(SRCDIR)/common_symbols2.inc $(BUILDDIR)/pipeline.o $(BUILDDIR)/pipeline.dbg.obj: $(SRCDIR)/passes.h $(SRCDIR)/jitlayers.h -$(addprefix $(BUILDDIR)/,threading.o threading.dbg.obj gc.o gc.dbg.obj init.c init.dbg.obj task.o task.dbg.obj): $(addprefix $(SRCDIR)/,threading.h) +$(addprefix $(BUILDDIR)/,threading.o threading.dbg.obj gc-common.o gc-stock.o gc.dbg.obj init.c init.dbg.obj task.o task.dbg.obj): $(addprefix $(SRCDIR)/,threading.h) $(addprefix $(BUILDDIR)/,APInt-C.o APInt-C.dbg.obj runtime_intrinsics.o runtime_intrinsics.dbg.obj): $(SRCDIR)/APInt-C.h # archive library file rules diff --git a/src/abi_aarch64.cpp b/src/abi_aarch64.cpp index 7c31b6606139a..0a193ee132556 100644 --- a/src/abi_aarch64.cpp +++ b/src/abi_aarch64.cpp @@ -16,7 +16,7 @@ struct ABI_AArch64Layout : AbiLayout { Type *get_llvm_vectype(jl_datatype_t *dt, LLVMContext &ctx) const { // Assume jl_is_datatype(dt) && !jl_is_abstracttype(dt) - // `!dt->name->mutabl && dt->pointerfree && !dt->haspadding && dt->nfields > 0` + // `!dt->name->mutabl && dt->pointerfree && !dt->haspadding && dt->isbitsegal && dt->nfields > 0` if (dt->layout == NULL || jl_is_layout_opaque(dt->layout)) return nullptr; size_t nfields = dt->layout->nfields; @@ -62,7 +62,7 @@ Type *get_llvm_vectype(jl_datatype_t *dt, LLVMContext &ctx) const Type *get_llvm_fptype(jl_datatype_t *dt, LLVMContext &ctx) const { // Assume jl_is_datatype(dt) && !jl_is_abstracttype(dt) - // `!dt->name->mutabl && dt->pointerfree && !dt->haspadding && dt->nfields == 0` + // `!dt->name->mutabl && dt->pointerfree && !dt->haspadding && dt->isbitsegal && dt->nfields == 0` Type *lltype; // Check size first since it's cheaper. switch (jl_datatype_size(dt)) { @@ -88,7 +88,7 @@ Type *get_llvm_fptype(jl_datatype_t *dt, LLVMContext &ctx) const Type *get_llvm_fp_or_vectype(jl_datatype_t *dt, LLVMContext &ctx) const { // Assume jl_is_datatype(dt) && !jl_is_abstracttype(dt) - if (dt->name->mutabl || dt->layout->npointers || dt->layout->flags.haspadding) + if (dt->name->mutabl || dt->layout->npointers || !dt->layout->flags.isbitsegal || dt->layout->flags.haspadding) return nullptr; return dt->layout->nfields ? get_llvm_vectype(dt, ctx) : get_llvm_fptype(dt, ctx); } @@ -184,7 +184,7 @@ Type *isHFAorHVA(jl_datatype_t *dt, size_t &nele, LLVMContext &ctx) const // uniquely addressable members. // Maximum HFA and HVA size is 64 bytes (4 x fp128 or 16bytes vector) size_t dsz = jl_datatype_size(dt); - if (dsz > 64 || !dt->layout || dt->layout->npointers || dt->layout->flags.haspadding) + if (dsz > 64 || !dt->layout || dt->layout->npointers || !dt->layout->flags.isbitsegal || dt->layout->flags.haspadding) return NULL; nele = 0; ElementType eltype; diff --git a/src/abi_arm.cpp b/src/abi_arm.cpp index 68f980d7b40da..8839a37da6e13 100644 --- a/src/abi_arm.cpp +++ b/src/abi_arm.cpp @@ -82,7 +82,7 @@ size_t isLegalHA(jl_datatype_t *dt, Type *&base, LLVMContext &ctx) const if (jl_is_structtype(dt)) { // Fast path checks before descending the type hierarchy // (4 x 128b vector == 64B max size) - if (jl_datatype_size(dt) > 64 || dt->layout->npointers || dt->layout->flags.haspadding) + if (jl_datatype_size(dt) > 64 || dt->layout->npointers || !dt->layout->flags.isbitsegal || dt->layout->flags.haspadding) return 0; base = NULL; diff --git a/src/abi_ppc64le.cpp b/src/abi_ppc64le.cpp index 1f10817cfeeee..f02e1022ddc2d 100644 --- a/src/abi_ppc64le.cpp +++ b/src/abi_ppc64le.cpp @@ -44,7 +44,7 @@ struct ABI_PPC64leLayout : AbiLayout { // count the homogeneous floating aggregate size (saturating at max count of 8) unsigned isHFA(jl_datatype_t *ty, jl_datatype_t **ty0, bool *hva) const { - if (jl_datatype_size(ty) > 128 || ty->layout->npointers || ty->layout->flags.haspadding) + if (jl_datatype_size(ty) > 128 || ty->layout->npointers || !ty->layout->flags.isbitsegal || ty->layout->flags.haspadding) return 9; size_t i, l = ty->layout->nfields; diff --git a/src/aotcompile.cpp b/src/aotcompile.cpp index 815e305d14376..48afa360c0037 100644 --- a/src/aotcompile.cpp +++ b/src/aotcompile.cpp @@ -19,24 +19,9 @@ // analysis passes #include -#include -#include -#include #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include #include #include @@ -1164,7 +1149,11 @@ static AOTOutputs add_output_impl(Module &M, TargetMachine &SourceTM, ShardTimer raw_svector_ostream OS(out.obj); legacy::PassManager emitter; addTargetPasses(&emitter, TM->getTargetTriple(), TM->getTargetIRAnalysis()); +#if JL_LLVM_VERSION >= 180000 + if (TM->addPassesToEmitFile(emitter, OS, nullptr, CodeGenFileType::ObjectFile, false)) +#else if (TM->addPassesToEmitFile(emitter, OS, nullptr, CGFT_ObjectFile, false)) +#endif jl_safe_printf("ERROR: target does not support generation of object files\n"); emitter.run(M); timers.obj.stopTimer(); @@ -1175,7 +1164,11 @@ static AOTOutputs add_output_impl(Module &M, TargetMachine &SourceTM, ShardTimer raw_svector_ostream OS(out.asm_); legacy::PassManager emitter; addTargetPasses(&emitter, TM->getTargetTriple(), TM->getTargetIRAnalysis()); +#if JL_LLVM_VERSION >= 180000 + if (TM->addPassesToEmitFile(emitter, OS, nullptr, CodeGenFileType::AssemblyFile, false)) +#else if (TM->addPassesToEmitFile(emitter, OS, nullptr, CGFT_AssemblyFile, false)) +#endif jl_safe_printf("ERROR: target does not support generation of assembly files\n"); emitter.run(M); timers.asm_.stopTimer(); @@ -1632,7 +1625,11 @@ void jl_dump_native_impl(void *native_code, jl_ExecutionEngine->getTargetOptions(), RelocModel, CMModel, +#if JL_LLVM_VERSION >= 180000 + CodeGenOptLevel::Aggressive // -O3 TODO: respect command -O0 flag? +#else CodeGenOpt::Aggressive // -O3 TODO: respect command -O0 flag? +#endif )); fixupTM(*SourceTM); auto DL = jl_create_datalayout(*SourceTM); @@ -1892,26 +1889,31 @@ void jl_dump_native_impl(void *native_code, JL_TIMING(NATIVE_AOT, NATIVE_Write); object::Archive::Kind Kind = getDefaultForHost(TheTriple); +#if JL_LLVM_VERSION >= 180000 +#define WritingMode SymtabWritingMode::NormalSymtab +#else +#define WritingMode true +#endif #define WRITE_ARCHIVE(fname, field, prefix, suffix) \ - if (fname) {\ - SmallVector archive; \ - SmallVector filenames; \ - SmallVector buffers; \ - for (size_t i = 0; i < threads; i++) { \ - filenames.push_back((StringRef("text") + prefix + "#" + Twine(i) + suffix).str()); \ - buffers.push_back(StringRef(data_outputs[i].field.data(), data_outputs[i].field.size())); \ - } \ - filenames.push_back("metadata" prefix suffix); \ - buffers.push_back(StringRef(metadata_outputs[0].field.data(), metadata_outputs[0].field.size())); \ - if (z) { \ - filenames.push_back("sysimg" prefix suffix); \ - buffers.push_back(StringRef(sysimg_outputs[0].field.data(), sysimg_outputs[0].field.size())); \ - } \ - for (size_t i = 0; i < filenames.size(); i++) { \ - archive.push_back(NewArchiveMember(MemoryBufferRef(buffers[i], filenames[i]))); \ - } \ - handleAllErrors(writeArchive(fname, archive, true, Kind, true, false), reportWriterError); \ - } + if (fname) {\ + SmallVector archive; \ + SmallVector filenames; \ + SmallVector buffers; \ + for (size_t i = 0; i < threads; i++) { \ + filenames.push_back((StringRef("text") + prefix + "#" + Twine(i) + suffix).str()); \ + buffers.push_back(StringRef(data_outputs[i].field.data(), data_outputs[i].field.size())); \ + } \ + filenames.push_back("metadata" prefix suffix); \ + buffers.push_back(StringRef(metadata_outputs[0].field.data(), metadata_outputs[0].field.size())); \ + if (z) { \ + filenames.push_back("sysimg" prefix suffix); \ + buffers.push_back(StringRef(sysimg_outputs[0].field.data(), sysimg_outputs[0].field.size())); \ + } \ + for (size_t i = 0; i < filenames.size(); i++) { \ + archive.push_back(NewArchiveMember(MemoryBufferRef(buffers[i], filenames[i]))); \ + } \ + handleAllErrors(writeArchive(fname, archive, WritingMode, Kind, true, false), reportWriterError); \ + } WRITE_ARCHIVE(unopt_bc_fname, unopt, "_unopt", ".bc"); WRITE_ARCHIVE(bc_fname, opt, "_opt", ".bc"); diff --git a/src/builtins.c b/src/builtins.c index 8cc1465592068..045a9914f5078 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -2084,6 +2084,12 @@ static int references_name(jl_value_t *p, jl_typename_t *name, int affects_layou return references_name(((jl_uniontype_t*)p)->a, name, affects_layout, freevars) || references_name(((jl_uniontype_t*)p)->b, name, affects_layout, freevars); } + if (jl_is_vararg(p)) { + jl_value_t *T = ((jl_vararg_t*)p)->T; + jl_value_t *N = ((jl_vararg_t*)p)->N; + return (T && references_name(T, name, affects_layout, freevars)) || + (N && references_name(N, name, affects_layout, freevars)); + } if (jl_is_typevar(p)) return 0; // already checked by unionall, if applicable if (jl_is_datatype(p)) { diff --git a/src/ccall.cpp b/src/ccall.cpp index 3c2857608c163..97315d46b6ead 100644 --- a/src/ccall.cpp +++ b/src/ccall.cpp @@ -554,8 +554,8 @@ static Value *julia_to_native( // pass the address of an alloca'd thing, not a box // since those are immutable. Value *slot = emit_static_alloca(ctx, to); - unsigned align = julia_alignment(jlto); - cast(slot)->setAlignment(Align(align)); + Align align(julia_alignment(jlto)); + cast(slot)->setAlignment(align); setName(ctx.emission_context, slot, "native_convert_buffer"); if (!jvinfo.ispointer()) { jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, jvinfo.tbaa); @@ -2108,7 +2108,7 @@ jl_cgval_t function_sig_t::emit_a_ccall( if (!isa(llvmf) || cast(llvmf)->isIntrinsic() || cast(llvmf)->getFunctionType() != functype) llvmf = NULL; } - else if (f_name.startswith("llvm.")) { + else if (f_name.starts_with("llvm.")) { // compute and verify auto-mangling for intrinsic name auto ID = Function::lookupIntrinsicID(f_name); if (ID != Intrinsic::not_intrinsic) { @@ -2230,7 +2230,7 @@ jl_cgval_t function_sig_t::emit_a_ccall( Value *strct = emit_allocobj(ctx, (jl_datatype_t*)rt, true); setName(ctx.emission_context, strct, "ccall_ret_box"); MDNode *tbaa = jl_is_mutable(rt) ? ctx.tbaa().tbaa_mutab : ctx.tbaa().tbaa_immut; - int boxalign = julia_alignment(rt); + Align boxalign(julia_alignment(rt)); // copy the data from the return value to the new struct const DataLayout &DL = ctx.builder.GetInsertBlock()->getModule()->getDataLayout(); auto resultTy = result->getType(); @@ -2240,8 +2240,8 @@ jl_cgval_t function_sig_t::emit_a_ccall( // When this happens, cast through memory. auto slot = emit_static_alloca(ctx, resultTy); setName(ctx.emission_context, slot, "type_pun_slot"); - slot->setAlignment(Align(boxalign)); - ctx.builder.CreateAlignedStore(result, slot, Align(boxalign)); + slot->setAlignment(boxalign); + ctx.builder.CreateAlignedStore(result, slot, boxalign); jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, tbaa); emit_memcpy(ctx, strct, ai, slot, ai, rtsz, boxalign, boxalign); } diff --git a/src/cgutils.cpp b/src/cgutils.cpp index 613d7ae719448..0969f78f10bb4 100644 --- a/src/cgutils.cpp +++ b/src/cgutils.cpp @@ -315,7 +315,7 @@ static Value *emit_pointer_from_objref(jl_codectx_t &ctx, Value *V) } static Value *emit_unbox(jl_codectx_t &ctx, Type *to, const jl_cgval_t &x, jl_value_t *jt); -static void emit_unbox_store(jl_codectx_t &ctx, const jl_cgval_t &x, Value* dest, MDNode *tbaa_dest, unsigned alignment, bool isVolatile=false); +static void emit_unbox_store(jl_codectx_t &ctx, const jl_cgval_t &x, Value* dest, MDNode *tbaa_dest, Align alignment, bool isVolatile=false); static bool type_is_permalloc(jl_value_t *typ) { @@ -1006,11 +1006,10 @@ static Value *data_pointer(jl_codectx_t &ctx, const jl_cgval_t &x) } static void emit_memcpy_llvm(jl_codectx_t &ctx, Value *dst, jl_aliasinfo_t const &dst_ai, Value *src, - jl_aliasinfo_t const &src_ai, uint64_t sz, unsigned align_dst, unsigned align_src, bool is_volatile) + jl_aliasinfo_t const &src_ai, uint64_t sz, Align align_dst, Align align_src, bool is_volatile) { if (sz == 0) return; - assert(align_dst && "align must be specified"); #if JL_LLVM_VERSION < 170000 // If the types are small and simple, use load and store directly. // Going through memcpy can cause LLVM (e.g. SROA) to create bitcasts between float and int @@ -1053,7 +1052,7 @@ static void emit_memcpy_llvm(jl_codectx_t &ctx, Value *dst, jl_aliasinfo_t const if (isa(dst) && !dst->hasName()) setName(ctx.emission_context, dst, "memcpy_refined_dst"); auto val = src_ai.decorateInst(ctx.builder.CreateAlignedLoad(directel, src, MaybeAlign(align_src), is_volatile)); - dst_ai.decorateInst(ctx.builder.CreateAlignedStore(val, dst, Align(align_dst), is_volatile)); + dst_ai.decorateInst(ctx.builder.CreateAlignedStore(val, dst, align_dst, is_volatile)); ++SkippedMemcpys; return; } @@ -1072,12 +1071,12 @@ static void emit_memcpy_llvm(jl_codectx_t &ctx, Value *dst, jl_aliasinfo_t const // above problem won't be as serious. auto merged_ai = dst_ai.merge(src_ai); - ctx.builder.CreateMemCpy(dst, Align(align_dst), src, Align(align_src), sz, is_volatile, + ctx.builder.CreateMemCpy(dst, align_dst, src, align_src, sz, is_volatile, merged_ai.tbaa, merged_ai.tbaa_struct, merged_ai.scope, merged_ai.noalias); } static void emit_memcpy_llvm(jl_codectx_t &ctx, Value *dst, jl_aliasinfo_t const &dst_ai, Value *src, - jl_aliasinfo_t const &src_ai, Value *sz, unsigned align_dst, unsigned align_src, bool is_volatile) + jl_aliasinfo_t const &src_ai, Value *sz, Align align_dst, Align align_src, bool is_volatile) { if (auto const_sz = dyn_cast(sz)) { emit_memcpy_llvm(ctx, dst, dst_ai, src, src_ai, const_sz->getZExtValue(), align_dst, align_src, is_volatile); @@ -1086,20 +1085,20 @@ static void emit_memcpy_llvm(jl_codectx_t &ctx, Value *dst, jl_aliasinfo_t const ++EmittedMemcpys; auto merged_ai = dst_ai.merge(src_ai); - ctx.builder.CreateMemCpy(dst, MaybeAlign(align_dst), src, MaybeAlign(align_src), sz, is_volatile, + ctx.builder.CreateMemCpy(dst, align_dst, src, align_src, sz, is_volatile, merged_ai.tbaa, merged_ai.tbaa_struct, merged_ai.scope, merged_ai.noalias); } template static void emit_memcpy(jl_codectx_t &ctx, Value *dst, jl_aliasinfo_t const &dst_ai, Value *src, - jl_aliasinfo_t const &src_ai, T1 &&sz, unsigned align_dst, unsigned align_src, bool is_volatile=false) + jl_aliasinfo_t const &src_ai, T1 &&sz, Align align_dst, Align align_src, bool is_volatile=false) { emit_memcpy_llvm(ctx, dst, dst_ai, src, src_ai, sz, align_dst, align_src, is_volatile); } template static void emit_memcpy(jl_codectx_t &ctx, Value *dst, jl_aliasinfo_t const &dst_ai, const jl_cgval_t &src, - T1 &&sz, unsigned align_dst, unsigned align_src, bool is_volatile=false) + T1 &&sz, Align align_dst, Align align_src, bool is_volatile=false) { auto src_ai = jl_aliasinfo_t::fromTBAA(ctx, src.tbaa); emit_memcpy_llvm(ctx, dst, dst_ai, data_pointer(ctx, src), src_ai, sz, align_dst, align_src, is_volatile); @@ -1999,7 +1998,7 @@ static jl_cgval_t typed_load(jl_codectx_t &ctx, Value *ptr, Value *idx_0based, j else if (!alignment) alignment = julia_alignment(jltype); if (intcast && Order == AtomicOrdering::NotAtomic) { - emit_memcpy(ctx, intcast, jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_stack), data, jl_aliasinfo_t::fromTBAA(ctx, tbaa), nb, alignment, intcast->getAlign().value()); + emit_memcpy(ctx, intcast, jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_stack), data, jl_aliasinfo_t::fromTBAA(ctx, tbaa), nb, Align(alignment), intcast->getAlign()); } else { if (!isboxed && jl_is_genericmemoryref_type(jltype)) { @@ -2120,12 +2119,15 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx, FailOrder = AtomicOrdering::Monotonic; unsigned nb = isboxed ? sizeof(void*) : jl_datatype_size(jltype); AllocaInst *intcast = nullptr; + Type *intcast_eltyp = nullptr; + bool tracked_pointers = isboxed || CountTrackedPointers(elty).count > 0; if (!isboxed && Order != AtomicOrdering::NotAtomic && !elty->isIntOrPtrTy()) { + intcast_eltyp = elty; + elty = Type::getIntNTy(ctx.builder.getContext(), 8 * nb); if (!issetfield) { intcast = emit_static_alloca(ctx, elty); setName(ctx.emission_context, intcast, "atomic_store_box"); } - elty = Type::getIntNTy(ctx.builder.getContext(), 8 * nb); } Type *realelty = elty; if (Order != AtomicOrdering::NotAtomic && isa(elty)) { @@ -2134,14 +2136,20 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx, elty = Type::getIntNTy(ctx.builder.getContext(), 8 * nb2); } Value *r = nullptr; - if (issetfield || isswapfield || isreplacefield || issetfieldonce) { - if (isboxed) + if (issetfield || isswapfield || isreplacefield || issetfieldonce) { // e.g. !ismodifyfield + assert(isboxed || rhs.typ == jltype); + if (isboxed) { r = boxed(ctx, rhs); - else if (aliasscope || Order != AtomicOrdering::NotAtomic || CountTrackedPointers(realelty).count) { + } + else if (intcast) { + emit_unbox_store(ctx, rhs, intcast, ctx.tbaa().tbaa_stack, intcast->getAlign()); + r = ctx.builder.CreateLoad(realelty, intcast); + } + else if (aliasscope || Order != AtomicOrdering::NotAtomic || tracked_pointers) { r = emit_unbox(ctx, realelty, rhs, jltype); - if (realelty != elty) - r = ctx.builder.CreateZExt(r, elty); } + if (realelty != elty) + r = ctx.builder.CreateZExt(r, elty); } if (isboxed) alignment = sizeof(void*); @@ -2176,7 +2184,7 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx, } else { assert(Order == AtomicOrdering::NotAtomic && !isboxed && rhs.typ == jltype); - emit_unbox_store(ctx, rhs, ptr, tbaa, alignment); + emit_unbox_store(ctx, rhs, ptr, tbaa, Align(alignment)); } } else if (isswapfield) { @@ -2223,7 +2231,14 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx, Current->addIncoming(instr, SkipBB); ctx.builder.SetInsertPoint(BB); } - Compare = emit_unbox(ctx, realelty, cmp, jltype); + cmp = update_julia_type(ctx, cmp, jltype); + if (intcast) { + emit_unbox_store(ctx, cmp, intcast, ctx.tbaa().tbaa_stack, intcast->getAlign()); + Compare = ctx.builder.CreateLoad(realelty, intcast); + } + else { + Compare = emit_unbox(ctx, realelty, cmp, jltype); + } if (realelty != elty) Compare = ctx.builder.CreateZExt(Compare, elty); } @@ -2270,16 +2285,17 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx, if (realelty != elty) realCompare = ctx.builder.CreateTrunc(realCompare, realelty); if (intcast) { + assert(!isboxed); ctx.builder.CreateStore(realCompare, intcast); - if (maybe_null_if_boxed) - realCompare = ctx.builder.CreateLoad(intcast->getAllocatedType(), intcast); + if (tracked_pointers) + realCompare = ctx.builder.CreateLoad(intcast_eltyp, intcast); } - if (maybe_null_if_boxed) { - Value *first_ptr = isboxed ? Compare : extract_first_ptr(ctx, Compare); - if (first_ptr) - null_load_check(ctx, first_ptr, mod, var); + if (maybe_null_if_boxed && tracked_pointers) { + Value *first_ptr = isboxed ? realCompare : extract_first_ptr(ctx, realCompare); + assert(first_ptr); + null_load_check(ctx, first_ptr, mod, var); } - if (intcast) + if (intcast && !tracked_pointers) oldval = mark_julia_slot(intcast, jltype, NULL, ctx.tbaa().tbaa_stack); else oldval = mark_julia_type(ctx, realCompare, isboxed, jltype); @@ -2287,11 +2303,18 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx, if (isboxed) { r = boxed(ctx, rhs); } - else if (Order != AtomicOrdering::NotAtomic || CountTrackedPointers(realelty).count) { + else if (intcast) { + emit_unbox_store(ctx, rhs, intcast, ctx.tbaa().tbaa_stack, intcast->getAlign()); + r = ctx.builder.CreateLoad(realelty, intcast); + if (!tracked_pointers) // oldval is a slot, so put the oldval back + ctx.builder.CreateStore(realCompare, intcast); + } + else if (Order != AtomicOrdering::NotAtomic) { + assert(!tracked_pointers); r = emit_unbox(ctx, realelty, rhs, jltype); - if (realelty != elty) - r = ctx.builder.CreateZExt(r, elty); } + if (realelty != elty) + r = ctx.builder.CreateZExt(r, elty); if (needlock) emit_lockstate_value(ctx, needlock, true); cmp = oldval; @@ -2329,7 +2352,7 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx, } else { assert(!isboxed && rhs.typ == jltype); - emit_unbox_store(ctx, rhs, ptr, tbaa, alignment); + emit_unbox_store(ctx, rhs, ptr, tbaa, Align(alignment)); } ctx.builder.CreateBr(DoneBB); instr = load; @@ -2357,9 +2380,10 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx, realinstr = ctx.builder.CreateTrunc(realinstr, realelty); if (intcast) { ctx.builder.CreateStore(realinstr, intcast); + // n.b. this oldval is only used for emit_f_is in this branch, so we know a priori that it does not need a gc-root oldval = mark_julia_slot(intcast, jltype, NULL, ctx.tbaa().tbaa_stack); if (maybe_null_if_boxed) - realinstr = ctx.builder.CreateLoad(intcast->getAllocatedType(), intcast); + realinstr = ctx.builder.CreateLoad(intcast_eltyp, intcast); } else { oldval = mark_julia_type(ctx, realinstr, isboxed, jltype); @@ -2399,20 +2423,23 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx, ctx.builder.SetInsertPoint(DoneBB); if (needlock) emit_lockstate_value(ctx, needlock, false); - if (parent != NULL) { + if (parent != NULL && r && tracked_pointers && (!isboxed || !type_is_permalloc(rhs.typ))) { if (isreplacefield || issetfieldonce) { - // TODO: avoid this branch if we aren't making a write barrier BasicBlock *BB = BasicBlock::Create(ctx.builder.getContext(), "xchg_wb", ctx.f); DoneBB = BasicBlock::Create(ctx.builder.getContext(), "done_xchg_wb", ctx.f); ctx.builder.CreateCondBr(Success, BB, DoneBB); ctx.builder.SetInsertPoint(BB); } - if (r) { - if (!isboxed) - emit_write_multibarrier(ctx, parent, r, rhs.typ); - else if (!type_is_permalloc(rhs.typ)) - emit_write_barrier(ctx, parent, r); + if (realelty != elty) + r = ctx.builder.Insert(CastInst::Create(Instruction::Trunc, r, realelty)); + if (intcast) { + ctx.builder.CreateStore(r, intcast); + r = ctx.builder.CreateLoad(intcast_eltyp, intcast); } + if (!isboxed) + emit_write_multibarrier(ctx, parent, r, rhs.typ); + else if (!type_is_permalloc(rhs.typ)) + emit_write_barrier(ctx, parent, r); if (isreplacefield || issetfieldonce) { ctx.builder.CreateBr(DoneBB); ctx.builder.SetInsertPoint(DoneBB); @@ -2431,21 +2458,18 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx, instr = ctx.builder.Insert(CastInst::Create(Instruction::Trunc, instr, realelty)); if (intcast) { ctx.builder.CreateStore(instr, intcast); - instr = nullptr; + if (tracked_pointers) + instr = ctx.builder.CreateLoad(intcast_eltyp, intcast); } - if (maybe_null_if_boxed) { - if (intcast) - instr = ctx.builder.CreateLoad(intcast->getAllocatedType(), intcast); + if (maybe_null_if_boxed && tracked_pointers) { Value *first_ptr = isboxed ? instr : extract_first_ptr(ctx, instr); - if (first_ptr) - null_load_check(ctx, first_ptr, mod, var); - if (intcast && !first_ptr) - instr = nullptr; + assert(first_ptr); + null_load_check(ctx, first_ptr, mod, var); } - if (instr) - oldval = mark_julia_type(ctx, instr, isboxed, jltype); - else + if (intcast && !tracked_pointers) oldval = mark_julia_slot(intcast, jltype, NULL, ctx.tbaa().tbaa_stack); + else + oldval = mark_julia_type(ctx, instr, isboxed, jltype); if (isreplacefield) { Success = ctx.builder.CreateZExt(Success, getInt8Ty(ctx.builder.getContext())); const jl_cgval_t argv[2] = {oldval, mark_julia_type(ctx, Success, false, jl_bool_type)}; @@ -2668,7 +2692,7 @@ static jl_cgval_t emit_unionload(jl_codectx_t &ctx, Value *addr, Value *ptindex, if (al > 1) lv->setAlignment(Align(al)); jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, tbaa); - emit_memcpy(ctx, lv, ai, addr, ai, fsz, al, al); + emit_memcpy(ctx, lv, ai, addr, ai, fsz, Align(al), Align(al)); addr = lv; } return mark_julia_slot(fsz > 0 ? addr : nullptr, jfty, tindex, tbaa); @@ -3104,11 +3128,11 @@ static Value *emit_genericmemoryowner(jl_codectx_t &ctx, Value *t) static Value *emit_allocobj(jl_codectx_t &ctx, jl_datatype_t *jt, bool fully_initialized); static void init_bits_value(jl_codectx_t &ctx, Value *newv, Value *v, MDNode *tbaa, - unsigned alignment = sizeof(void*)) // min alignment in julia's gc is pointer-aligned + Align alignment = Align(sizeof(void*))) // min alignment in julia's gc is pointer-aligned { jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, tbaa); // newv should already be tagged - ai.decorateInst(ctx.builder.CreateAlignedStore(v, newv, Align(alignment))); + ai.decorateInst(ctx.builder.CreateAlignedStore(v, newv, alignment)); } static void init_bits_cgval(jl_codectx_t &ctx, Value *newv, const jl_cgval_t& v, MDNode *tbaa) @@ -3116,7 +3140,7 @@ static void init_bits_cgval(jl_codectx_t &ctx, Value *newv, const jl_cgval_t& v, // newv should already be tagged if (v.ispointer()) { unsigned align = std::max(julia_alignment(v.typ), (unsigned)sizeof(void*)); - emit_memcpy(ctx, newv, jl_aliasinfo_t::fromTBAA(ctx, tbaa), v, jl_datatype_size(v.typ), align, julia_alignment(v.typ)); + emit_memcpy(ctx, newv, jl_aliasinfo_t::fromTBAA(ctx, tbaa), v, jl_datatype_size(v.typ), Align(align), Align(julia_alignment(v.typ))); } else { init_bits_value(ctx, newv, v.V, tbaa); @@ -3582,7 +3606,7 @@ static void emit_unionmove(jl_codectx_t &ctx, Value *dest, MDNode *tbaa_dst, con if (jl_is_pointerfree(typ)) { unsigned alignment = julia_alignment(typ); if (!src.ispointer() || src.constant) { - emit_unbox_store(ctx, src, dest, tbaa_dst, alignment, isVolatile); + emit_unbox_store(ctx, src, dest, tbaa_dst, Align(alignment), isVolatile); } else { Value *src_ptr = data_pointer(ctx, src); @@ -3592,7 +3616,7 @@ static void emit_unionmove(jl_codectx_t &ctx, Value *dest, MDNode *tbaa_dst, con // if (skip) src_ptr = ctx.builder.CreateSelect(skip, dest, src_ptr); auto f = [&] { (void)emit_memcpy(ctx, dest, jl_aliasinfo_t::fromTBAA(ctx, tbaa_dst), src_ptr, - jl_aliasinfo_t::fromTBAA(ctx, src.tbaa), nb, alignment, alignment, isVolatile); + jl_aliasinfo_t::fromTBAA(ctx, src.tbaa), nb, Align(alignment), Align(alignment), isVolatile); return nullptr; }; if (skip) @@ -3627,7 +3651,7 @@ static void emit_unionmove(jl_codectx_t &ctx, Value *dest, MDNode *tbaa_dst, con return; } else { emit_memcpy(ctx, dest, jl_aliasinfo_t::fromTBAA(ctx, tbaa_dst), src_ptr, - jl_aliasinfo_t::fromTBAA(ctx, src.tbaa), nb, alignment, alignment, isVolatile); + jl_aliasinfo_t::fromTBAA(ctx, src.tbaa), nb, Align(alignment), Align(alignment), isVolatile); } } ctx.builder.CreateBr(postBB); @@ -3653,7 +3677,7 @@ static void emit_unionmove(jl_codectx_t &ctx, Value *dest, MDNode *tbaa_dst, con Value *datatype = emit_typeof(ctx, src, false, false); Value *copy_bytes = emit_datatype_size(ctx, datatype); (void)emit_memcpy(ctx, dest, jl_aliasinfo_t::fromTBAA(ctx, tbaa_dst), data_pointer(ctx, src), - jl_aliasinfo_t::fromTBAA(ctx, src.tbaa), copy_bytes, 1, 1, isVolatile); + jl_aliasinfo_t::fromTBAA(ctx, src.tbaa), copy_bytes, Align(1), Align(1), isVolatile); return nullptr; }; if (skip) @@ -3923,8 +3947,6 @@ static jl_cgval_t emit_new_struct(jl_codectx_t &ctx, jl_value_t *ty, size_t narg else { strct = emit_static_alloca(ctx, lt); setName(ctx.emission_context, strct, arg_typename); - if (nargs < nf) - promotion_point = ctx.builder.CreateStore(ctx.builder.CreateFreeze(UndefValue::get(lt)), strct); if (tracked.count) undef_derived_strct(ctx, strct, sty, ctx.tbaa().tbaa_stack); } @@ -4046,7 +4068,7 @@ static jl_cgval_t emit_new_struct(jl_codectx_t &ctx, jl_value_t *ty, size_t narg } else if (init_as_value) { fval = emit_unbox(ctx, fty, fval_info, jtype); } else { - emit_unbox_store(ctx, fval_info, dest, ctx.tbaa().tbaa_stack, jl_field_align(sty, i)); + emit_unbox_store(ctx, fval_info, dest, ctx.tbaa().tbaa_stack, Align(jl_field_align(sty, i))); } } if (init_as_value) { @@ -4080,6 +4102,14 @@ static jl_cgval_t emit_new_struct(jl_codectx_t &ctx, jl_value_t *ty, size_t narg } } } + if (promotion_point && nargs < nf) { + assert(!init_as_value); + IRBuilderBase::InsertPoint savedIP = ctx.builder.saveIP(); + ctx.builder.SetInsertPoint(promotion_point); + promotion_point = cast(ctx.builder.CreateFreeze(UndefValue::get(lt))); + ctx.builder.CreateStore(promotion_point, strct); + ctx.builder.restoreIP(savedIP); + } if (type_is_ghost(lt)) return mark_julia_const(ctx, sty->instance); else if (init_as_value) @@ -4262,9 +4292,8 @@ static jl_cgval_t emit_memoryref(jl_codectx_t &ctx, const jl_cgval_t &ref, jl_cg ovflw = ctx.builder.CreateICmpUGE(ctx.builder.CreateAdd(offset, mlen), ctx.builder.CreateNUWAdd(mlen, mlen)); } #endif - //Is this change fine boffset = ctx.builder.CreateMul(offset, elsz); - newdata = ctx.builder.CreateGEP(getInt8Ty(ctx.builder.getContext()), data, boffset); + newdata = ctx.builder.CreateInBoundsGEP(getInt8Ty(ctx.builder.getContext()), data, boffset); (void)boffset; // LLVM is very bad at handling GEP with types different from the load if (bc) { BasicBlock *failBB, *endBB; diff --git a/src/clangsa/GCChecker.cpp b/src/clangsa/GCChecker.cpp index 9caff014c7703..ecaeb460ebf91 100644 --- a/src/clangsa/GCChecker.cpp +++ b/src/clangsa/GCChecker.cpp @@ -767,7 +767,7 @@ bool GCChecker::isFDAnnotatedNotSafepoint(const clang::FunctionDecl *FD, const S SourceLocation Loc = FD->getLocation(); StringRef Name = SM.getFilename(Loc); Name = llvm::sys::path::filename(Name); - if (Name.startswith("llvm-")) + if (Name.starts_with("llvm-")) return true; return false; } @@ -911,9 +911,9 @@ bool GCChecker::isSafepoint(const CallEvent &Call, CheckerContext &C) const { if (FD->getBuiltinID() != 0 || FD->isTrivial()) isCalleeSafepoint = false; else if (FD->getDeclName().isIdentifier() && - (FD->getName().startswith("uv_") || - FD->getName().startswith("unw_") || - FD->getName().startswith("_U")) && + (FD->getName().starts_with("uv_") || + FD->getName().starts_with("unw_") || + FD->getName().starts_with("_U")) && FD->getName() != "uv_run") isCalleeSafepoint = false; else @@ -1050,13 +1050,13 @@ bool GCChecker::processAllocationOfResult(const CallEvent &Call, // global roots. StringRef FDName = FD->getDeclName().isIdentifier() ? FD->getName() : ""; - if (FDName.startswith("jl_box_") || FDName.startswith("ijl_box_")) { + if (FDName.starts_with("jl_box_") || FDName.starts_with("ijl_box_")) { SVal Arg = Call.getArgSVal(0); if (auto CI = Arg.getAs()) { const llvm::APSInt &Value = CI->getValue(); bool GloballyRooted = false; const int64_t NBOX_C = 1024; - if (FDName.startswith("jl_box_u") || FDName.startswith("ijl_box_u")) { + if (FDName.starts_with("jl_box_u") || FDName.starts_with("ijl_box_u")) { if (Value < NBOX_C) { GloballyRooted = true; } diff --git a/src/codegen-stubs.c b/src/codegen-stubs.c index 3e97c149bffe3..41812d903816c 100644 --- a/src/codegen-stubs.c +++ b/src/codegen-stubs.c @@ -107,8 +107,6 @@ JL_DLLEXPORT uint64_t jl_getUnwindInfo_fallback(uint64_t dwAddr) return 0; } -JL_DLLEXPORT void jl_build_newpm_pipeline_fallback(void *MPM, void *PB, void *config) UNAVAILABLE - JL_DLLEXPORT void jl_register_passbuilder_callbacks_fallback(void *PB) { } #define MODULE_PASS(NAME, CLASS, CREATE_PASS) \ diff --git a/src/codegen.cpp b/src/codegen.cpp index 875beb7c287dc..6551f13ea566e 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -2180,7 +2180,7 @@ static GlobalVariable *get_pointer_to_constant(jl_codegen_params_t &emission_con gv = get_gv(gvname); } } - assert(gv->getName().startswith(name.str())); + assert(gv->getName().starts_with(name.str())); assert(val == gv->getInitializer()); return gv; } @@ -3374,11 +3374,14 @@ static size_t emit_masked_bits_compare(callback &emit_desc, jl_datatype_t *aty, size_t padding_bytes = 0; size_t nfields = jl_datatype_nfields(aty); size_t total_size = jl_datatype_size(aty); + assert(aty->layout->flags.isbitsegal); for (size_t i = 0; i < nfields; ++i) { size_t offset = jl_field_offset(aty, i); size_t fend = i == nfields - 1 ? total_size : jl_field_offset(aty, i + 1); size_t fsz = jl_field_size(aty, i); jl_datatype_t *fty = (jl_datatype_t*)jl_field_type(aty, i); + assert(jl_is_datatype(fty)); // union fields should never reach here + assert(fty->layout->flags.isbitsegal); if (jl_field_isptr(aty, i) || !fty->layout->flags.haspadding) { // The field has no internal padding data_bytes += fsz; @@ -5652,7 +5655,7 @@ static jl_cgval_t emit_varinfo(jl_codectx_t &ctx, jl_varinfo_t &vi, jl_sym_t *va else { const DataLayout &DL = jl_Module->getDataLayout(); uint64_t sz = DL.getTypeStoreSize(T); - emit_memcpy(ctx, ssaslot, jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_stack), vi.value, sz, ssaslot->getAlign().value(), varslot->getAlign().value()); + emit_memcpy(ctx, ssaslot, jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_stack), vi.value, sz, ssaslot->getAlign(), varslot->getAlign()); } Value *tindex = NULL; if (vi.pTIndex) @@ -5756,8 +5759,9 @@ static void emit_vi_assignment_unboxed(jl_codectx_t &ctx, jl_varinfo_t &vi, Valu // This check should probably mostly catch the relevant situations. if (vi.value.V != rval_info.V) { Value *copy_bytes = ConstantInt::get(getInt32Ty(ctx.builder.getContext()), jl_datatype_size(vi.value.typ)); + Align alignment(julia_alignment(rval_info.typ)); emit_memcpy(ctx, vi.value.V, jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_stack), rval_info, copy_bytes, - julia_alignment(rval_info.typ), julia_alignment(rval_info.typ), vi.isVolatile); + alignment, alignment, vi.isVolatile); } } else { @@ -6868,8 +6872,9 @@ static void emit_cfunc_invalidate( root1 = ctx.builder.CreateConstInBoundsGEP2_32(get_returnroots_type(ctx, return_roots), root1, 0, 0); ctx.builder.CreateStore(gf_ret, root1); } + Align alignment(julia_alignment(rettype)); emit_memcpy(ctx, &*gf_thunk->arg_begin(), jl_aliasinfo_t::fromTBAA(ctx, nullptr), gf_ret, - jl_aliasinfo_t::fromTBAA(ctx, nullptr), jl_datatype_size(rettype), julia_alignment(rettype), julia_alignment(rettype)); + jl_aliasinfo_t::fromTBAA(ctx, nullptr), jl_datatype_size(rettype), Align(alignment), Align(alignment)); ctx.builder.CreateRetVoid(); break; } @@ -8729,7 +8734,7 @@ static jl_llvm_functions_t jl_cgval_t closure_world = typed_load(ctx, worldaddr, NULL, (jl_value_t*)jl_long_type, nullptr, nullptr, false, AtomicOrdering::NotAtomic, false, ctx.types().alignof_ptr.value()); ctx.world_age_at_entry = closure_world.V; // The tls world in a OC is the world of the closure - emit_unbox_store(ctx, closure_world, world_age_field, ctx.tbaa().tbaa_gcframe, ctx.types().alignof_ptr.value()); + emit_unbox_store(ctx, closure_world, world_age_field, ctx.tbaa().tbaa_gcframe, ctx.types().alignof_ptr); // Load closure env Value *envaddr = ctx.builder.CreateInBoundsGEP( @@ -8846,7 +8851,7 @@ static jl_llvm_functions_t !jl_is_submodule(mod, jl_core_module)); }; auto in_tracked_path = [] (StringRef file) { // falls within an explicitly set file or directory - return jl_options.tracked_path != NULL && file.startswith(jl_options.tracked_path); + return jl_options.tracked_path != NULL && file.starts_with(jl_options.tracked_path); }; bool mod_is_user_mod = in_user_mod(ctx.module); bool mod_is_tracked = in_tracked_path(ctx.file); @@ -9272,8 +9277,9 @@ static jl_llvm_functions_t } if (returninfo.cc == jl_returninfo_t::SRet) { assert(jl_is_concrete_type(jlrettype)); + Align alignment(julia_alignment(jlrettype)); emit_memcpy(ctx, sret, jl_aliasinfo_t::fromTBAA(ctx, nullptr), retvalinfo, - jl_datatype_size(jlrettype), julia_alignment(jlrettype), julia_alignment(jlrettype)); + jl_datatype_size(jlrettype), alignment, alignment); } else { // must be jl_returninfo_t::Union emit_unionmove(ctx, sret, nullptr, retvalinfo, /*skip*/isboxed_union); @@ -9511,7 +9517,7 @@ static jl_llvm_functions_t // load of val) if the runtime type of val isn't phiType Value *isvalid = emit_isa_and_defined(ctx, val, phiType); emit_guarded_test(ctx, isvalid, nullptr, [&] { - emit_unbox_store(ctx, update_julia_type(ctx, val, phiType), dest, ctx.tbaa().tbaa_stack, julia_alignment(phiType)); + emit_unbox_store(ctx, update_julia_type(ctx, val, phiType), dest, ctx.tbaa().tbaa_stack, Align(julia_alignment(phiType))); return nullptr; }); } @@ -9538,7 +9544,7 @@ static jl_llvm_functions_t if (VN) V = Constant::getNullValue(ctx.types().T_prjlvalue); if (dest) - emit_unbox_store(ctx, val, dest, ctx.tbaa().tbaa_stack, julia_alignment(val.typ)); + emit_unbox_store(ctx, val, dest, ctx.tbaa().tbaa_stack, Align(julia_alignment(val.typ))); RTindex = ConstantInt::get(getInt8Ty(ctx.builder.getContext()), tindex); } } @@ -9638,7 +9644,7 @@ static jl_llvm_functions_t // make sure that anything we attempt to call has some inlining info, just in case optimization messed up // (except if we know that it is an intrinsic used in our prologue, which should never have its own debug subprogram) Function *F = call->getCalledFunction(); - if (!in_prologue || !F || !(F->isIntrinsic() || F->getName().startswith("julia.") || &I == restTuple)) { + if (!in_prologue || !F || !(F->isIntrinsic() || F->getName().starts_with("julia.") || &I == restTuple)) { I.setDebugLoc(topdebugloc); } } diff --git a/src/coverage.cpp b/src/coverage.cpp index c061276e66fd9..685370198ff13 100644 --- a/src/coverage.cpp +++ b/src/coverage.cpp @@ -207,7 +207,7 @@ extern "C" JL_DLLEXPORT void jl_write_coverage_data(const char *output) { if (output) { StringRef output_pattern(output); - if (output_pattern.endswith(".info")) + if (output_pattern.ends_with(".info")) write_lcov_data(coverageData, jl_format_filename(output_pattern.str().c_str())); } else { diff --git a/src/datatype.c b/src/datatype.c index d5ee3eb7074c3..5d35a7b55057d 100644 --- a/src/datatype.c +++ b/src/datatype.c @@ -83,6 +83,7 @@ JL_DLLEXPORT jl_typename_t *jl_new_typename_in(jl_sym_t *name, jl_module_t *modu tn->atomicfields = NULL; tn->constfields = NULL; tn->max_methods = 0; + tn->constprop_heustic = 0; return tn; } @@ -935,6 +936,10 @@ JL_DLLEXPORT jl_datatype_t *jl_new_primitivetype(jl_value_t *name, jl_module_t * jl_emptysvec, jl_emptysvec, jl_emptysvec, 0, 0, 0); uint32_t nbytes = (nbits + 7) / 8; uint32_t alignm = next_power_of_two(nbytes); +# if defined(_CPU_X86_) && !defined(_OS_WINDOWS_) + if (alignm == 8) + alignm = 4; +# endif if (alignm > MAX_ALIGN) alignm = MAX_ALIGN; // memoize isprimitivetype, since it is much easier than checking @@ -1249,7 +1254,7 @@ JL_DLLEXPORT int jl_atomic_cmpswap_bits(jl_datatype_t *dt, jl_value_t *y /* pre- } else if (nb == 1) { uint8_t *y8 = (uint8_t*)y; - assert(!dt->layout->flags.haspadding); + assert(dt->layout->flags.isbitsegal && !dt->layout->flags.haspadding); if (dt == et) { *y8 = *(uint8_t*)expected; uint8_t z8 = *(uint8_t*)src; @@ -1262,7 +1267,7 @@ JL_DLLEXPORT int jl_atomic_cmpswap_bits(jl_datatype_t *dt, jl_value_t *y /* pre- } else if (nb == 2) { uint16_t *y16 = (uint16_t*)y; - assert(!dt->layout->flags.haspadding); + assert(dt->layout->flags.isbitsegal && !dt->layout->flags.haspadding); if (dt == et) { *y16 = *(uint16_t*)expected; uint16_t z16 = *(uint16_t*)src; @@ -1280,7 +1285,7 @@ JL_DLLEXPORT int jl_atomic_cmpswap_bits(jl_datatype_t *dt, jl_value_t *y /* pre- uint32_t z32 = zext_read32(src, nb); while (1) { success = jl_atomic_cmpswap((_Atomic(uint32_t)*)dst, y32, z32); - if (success || !dt->layout->flags.haspadding || !jl_egal__bits(y, expected, dt)) + if (success || (dt->layout->flags.isbitsegal && !dt->layout->flags.haspadding) || !jl_egal__bits(y, expected, dt)) break; } } @@ -1297,7 +1302,7 @@ JL_DLLEXPORT int jl_atomic_cmpswap_bits(jl_datatype_t *dt, jl_value_t *y /* pre- uint64_t z64 = zext_read64(src, nb); while (1) { success = jl_atomic_cmpswap((_Atomic(uint64_t)*)dst, y64, z64); - if (success || !dt->layout->flags.haspadding || !jl_egal__bits(y, expected, dt)) + if (success || (dt->layout->flags.isbitsegal && !dt->layout->flags.haspadding) || !jl_egal__bits(y, expected, dt)) break; } } @@ -1315,7 +1320,7 @@ JL_DLLEXPORT int jl_atomic_cmpswap_bits(jl_datatype_t *dt, jl_value_t *y /* pre- jl_uint128_t z128 = zext_read128(src, nb); while (1) { success = jl_atomic_cmpswap((_Atomic(jl_uint128_t)*)dst, y128, z128); - if (success || !dt->layout->flags.haspadding || !jl_egal__bits(y, expected, dt)) + if (success || (dt->layout->flags.isbitsegal && !dt->layout->flags.haspadding) || !jl_egal__bits(y, expected, dt)) break; } } @@ -2009,7 +2014,7 @@ inline jl_value_t *modify_bits(jl_value_t *ty, char *p, uint8_t *psel, jl_value_ else { char *px = lock(p, parent, needlock, isatomic); int success = memcmp(px, (char*)r, fsz) == 0; - if (!success && ((jl_datatype_t*)rty)->layout->flags.haspadding) + if (!success && (!((jl_datatype_t*)rty)->layout->flags.isbitsegal || ((jl_datatype_t*)rty)->layout->flags.haspadding)) success = jl_egal__bits((jl_value_t*)px, r, (jl_datatype_t*)rty); if (success) { if (isunion) { @@ -2124,7 +2129,7 @@ inline jl_value_t *replace_bits(jl_value_t *ty, char *p, uint8_t *psel, jl_value success = (rty == jl_typeof(expected)); if (success) { success = memcmp((char*)r, (char*)expected, rsz) == 0; - if (!success && ((jl_datatype_t*)rty)->layout->flags.haspadding) + if (!success && (!((jl_datatype_t*)rty)->layout->flags.isbitsegal || ((jl_datatype_t*)rty)->layout->flags.haspadding)) success = jl_egal__bits(r, expected, (jl_datatype_t*)rty); } *((uint8_t*)r + fsz) = success ? 1 : 0; diff --git a/src/disasm.cpp b/src/disasm.cpp index b24c374607113..b71503c3f7a77 100644 --- a/src/disasm.cpp +++ b/src/disasm.cpp @@ -1224,7 +1224,11 @@ jl_value_t *jl_dump_function_asm_impl(jl_llvmf_dump_t* dump, char emit_mc, const addTargetPasses(&PM, TM->getTargetTriple(), TM->getTargetIRAnalysis()); if (emit_mc) { raw_svector_ostream obj_OS(ObjBufferSV); +#if JL_LLVM_VERSION >= 180000 + if (TM->addPassesToEmitFile(PM, obj_OS, nullptr, CodeGenFileType::ObjectFile, false, nullptr)) +#else if (TM->addPassesToEmitFile(PM, obj_OS, nullptr, CGFT_ObjectFile, false, nullptr)) +#endif return jl_an_empty_string; TSM->withModuleDo([&](Module &m) { PM.run(m); }); } diff --git a/src/gc-alloc-profiler.cpp b/src/gc-alloc-profiler.cpp index c7ee32269138a..5b462d48cd2de 100644 --- a/src/gc-alloc-profiler.cpp +++ b/src/gc-alloc-profiler.cpp @@ -3,7 +3,6 @@ #include "gc-alloc-profiler.h" #include "julia_internal.h" -#include "gc.h" #include "llvm/ADT/SmallVector.h" diff --git a/src/gc-common.c b/src/gc-common.c new file mode 100644 index 0000000000000..ee461b576ea9e --- /dev/null +++ b/src/gc-common.c @@ -0,0 +1,506 @@ +// This file is a part of Julia. License is MIT: https://julialang.org/license + +#include "gc-common.h" +#include "julia.h" +#include "julia_atomics.h" +#include "julia_gcext.h" +#include "julia_assert.h" +#include "threading.h" +#ifdef __GLIBC__ +#include // for malloc_trim +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +// =========================================================================== // +// GC Metrics +// =========================================================================== // + +jl_gc_num_t gc_num = {0}; + +// =========================================================================== // +// GC Callbacks +// =========================================================================== // + +jl_gc_callback_list_t *gc_cblist_root_scanner; +jl_gc_callback_list_t *gc_cblist_task_scanner; +jl_gc_callback_list_t *gc_cblist_pre_gc; +jl_gc_callback_list_t *gc_cblist_post_gc; +jl_gc_callback_list_t *gc_cblist_notify_external_alloc; +jl_gc_callback_list_t *gc_cblist_notify_external_free; +jl_gc_callback_list_t *gc_cblist_notify_gc_pressure; + +static void jl_gc_register_callback(jl_gc_callback_list_t **list, + jl_gc_cb_func_t func) +{ + while (*list != NULL) { + if ((*list)->func == func) + return; + list = &((*list)->next); + } + *list = (jl_gc_callback_list_t *)malloc_s(sizeof(jl_gc_callback_list_t)); + (*list)->next = NULL; + (*list)->func = func; +} + +static void jl_gc_deregister_callback(jl_gc_callback_list_t **list, + jl_gc_cb_func_t func) +{ + while (*list != NULL) { + if ((*list)->func == func) { + jl_gc_callback_list_t *tmp = *list; + (*list) = (*list)->next; + free(tmp); + return; + } + list = &((*list)->next); + } +} + +JL_DLLEXPORT void jl_gc_set_cb_root_scanner(jl_gc_cb_root_scanner_t cb, int enable) +{ + if (enable) + jl_gc_register_callback(&gc_cblist_root_scanner, (jl_gc_cb_func_t)cb); + else + jl_gc_deregister_callback(&gc_cblist_root_scanner, (jl_gc_cb_func_t)cb); +} + +JL_DLLEXPORT void jl_gc_set_cb_task_scanner(jl_gc_cb_task_scanner_t cb, int enable) +{ + if (enable) + jl_gc_register_callback(&gc_cblist_task_scanner, (jl_gc_cb_func_t)cb); + else + jl_gc_deregister_callback(&gc_cblist_task_scanner, (jl_gc_cb_func_t)cb); +} + +JL_DLLEXPORT void jl_gc_set_cb_pre_gc(jl_gc_cb_pre_gc_t cb, int enable) +{ + if (enable) + jl_gc_register_callback(&gc_cblist_pre_gc, (jl_gc_cb_func_t)cb); + else + jl_gc_deregister_callback(&gc_cblist_pre_gc, (jl_gc_cb_func_t)cb); +} + +JL_DLLEXPORT void jl_gc_set_cb_post_gc(jl_gc_cb_post_gc_t cb, int enable) +{ + if (enable) + jl_gc_register_callback(&gc_cblist_post_gc, (jl_gc_cb_func_t)cb); + else + jl_gc_deregister_callback(&gc_cblist_post_gc, (jl_gc_cb_func_t)cb); +} + +JL_DLLEXPORT void jl_gc_set_cb_notify_external_alloc(jl_gc_cb_notify_external_alloc_t cb, int enable) +{ + if (enable) + jl_gc_register_callback(&gc_cblist_notify_external_alloc, (jl_gc_cb_func_t)cb); + else + jl_gc_deregister_callback(&gc_cblist_notify_external_alloc, (jl_gc_cb_func_t)cb); +} + +JL_DLLEXPORT void jl_gc_set_cb_notify_external_free(jl_gc_cb_notify_external_free_t cb, int enable) +{ + if (enable) + jl_gc_register_callback(&gc_cblist_notify_external_free, (jl_gc_cb_func_t)cb); + else + jl_gc_deregister_callback(&gc_cblist_notify_external_free, (jl_gc_cb_func_t)cb); +} + +JL_DLLEXPORT void jl_gc_set_cb_notify_gc_pressure(jl_gc_cb_notify_gc_pressure_t cb, int enable) +{ + if (enable) + jl_gc_register_callback(&gc_cblist_notify_gc_pressure, (jl_gc_cb_func_t)cb); + else + jl_gc_deregister_callback(&gc_cblist_notify_gc_pressure, (jl_gc_cb_func_t)cb); +} + +// =========================================================================== // +// Finalization +// =========================================================================== // + +jl_mutex_t finalizers_lock; +arraylist_t finalizer_list_marked; +arraylist_t to_finalize; +JL_DLLEXPORT _Atomic(int) jl_gc_have_pending_finalizers = 0; + +void schedule_finalization(void *o, void *f) JL_NOTSAFEPOINT +{ + arraylist_push(&to_finalize, o); + arraylist_push(&to_finalize, f); + // doesn't need release, since we'll keep checking (on the reader) until we see the work and + // release our lock, and that will have a release barrier by then + jl_atomic_store_relaxed(&jl_gc_have_pending_finalizers, 1); +} + +void run_finalizer(jl_task_t *ct, void *o, void *ff) +{ + int ptr_finalizer = gc_ptr_tag(o, 1); + o = gc_ptr_clear_tag(o, 3); + if (ptr_finalizer) { + ((void (*)(void*))ff)((void*)o); + return; + } + JL_TRY { + size_t last_age = ct->world_age; + ct->world_age = jl_atomic_load_acquire(&jl_world_counter); + jl_apply_generic((jl_value_t*)ff, (jl_value_t**)&o, 1); + ct->world_age = last_age; + } + JL_CATCH { + jl_printf((JL_STREAM*)STDERR_FILENO, "error in running finalizer: "); + jl_static_show((JL_STREAM*)STDERR_FILENO, jl_current_exception(ct)); + jl_printf((JL_STREAM*)STDERR_FILENO, "\n"); + jlbacktrace(); // written to STDERR_FILENO + } +} + +// if `need_sync` is true, the `list` is the `finalizers` list of another +// thread and we need additional synchronizations +static void finalize_object(arraylist_t *list, jl_value_t *o, + arraylist_t *copied_list, int need_sync) JL_NOTSAFEPOINT +{ + // The acquire load makes sure that the first `len` objects are valid. + // If `need_sync` is true, all mutations of the content should be limited + // to the first `oldlen` elements and no mutation is allowed after the + // new length is published with the `cmpxchg` at the end of the function. + // This way, the mutation should not conflict with the owning thread, + // which only writes to locations later than `len` + // and will not resize the buffer without acquiring the lock. + size_t len = need_sync ? jl_atomic_load_acquire((_Atomic(size_t)*)&list->len) : list->len; + size_t oldlen = len; + void **items = list->items; + size_t j = 0; + for (size_t i = 0; i < len; i += 2) { + void *v = items[i]; + int move = 0; + if (o == (jl_value_t*)gc_ptr_clear_tag(v, 1)) { + void *f = items[i + 1]; + move = 1; + arraylist_push(copied_list, v); + arraylist_push(copied_list, f); + } + if (move || __unlikely(!v)) { + // remove item + } + else { + if (j < i) { + items[j] = items[i]; + items[j+1] = items[i+1]; + } + j += 2; + } + } + len = j; + if (oldlen == len) + return; + if (need_sync) { + // The memset needs to be unconditional since the thread might have + // already read the length. + // The `memset` (like any other content mutation) has to be done + // **before** the `cmpxchg` which publishes the length. + memset(&items[len], 0, (oldlen - len) * sizeof(void*)); + jl_atomic_cmpswap((_Atomic(size_t)*)&list->len, &oldlen, len); + } + else { + list->len = len; + } +} + +// The first two entries are assumed to be empty and the rest are assumed to +// be pointers to `jl_value_t` objects +static void jl_gc_push_arraylist(jl_task_t *ct, arraylist_t *list) JL_NOTSAFEPOINT +{ + void **items = list->items; + items[0] = (void*)JL_GC_ENCODE_PUSHARGS(list->len - 2); + items[1] = ct->gcstack; + ct->gcstack = (jl_gcframe_t*)items; +} + +// Same assumption as `jl_gc_push_arraylist`. Requires the finalizers lock +// to be hold for the current thread and will release the lock when the +// function returns. +static void jl_gc_run_finalizers_in_list(jl_task_t *ct, arraylist_t *list) JL_NOTSAFEPOINT_LEAVE +{ + // Avoid marking `ct` as non-migratable via an `@async` task (as noted in the docstring + // of `finalizer`) in a finalizer: + uint8_t sticky = ct->sticky; + // empty out the first two entries for the GC frame + arraylist_push(list, list->items[0]); + arraylist_push(list, list->items[1]); + jl_gc_push_arraylist(ct, list); + void **items = list->items; + size_t len = list->len; + JL_UNLOCK_NOGC(&finalizers_lock); + // run finalizers in reverse order they were added, so lower-level finalizers run last + for (size_t i = len-4; i >= 2; i -= 2) + run_finalizer(ct, items[i], items[i + 1]); + // first entries were moved last to make room for GC frame metadata + run_finalizer(ct, items[len-2], items[len-1]); + // matches the jl_gc_push_arraylist above + JL_GC_POP(); + ct->sticky = sticky; +} + +static uint64_t finalizer_rngState[JL_RNG_SIZE]; + +void jl_rng_split(uint64_t dst[JL_RNG_SIZE], uint64_t src[JL_RNG_SIZE]) JL_NOTSAFEPOINT; + +JL_DLLEXPORT void jl_gc_init_finalizer_rng_state(void) +{ + jl_rng_split(finalizer_rngState, jl_current_task->rngState); +} + +void run_finalizers(jl_task_t *ct, int finalizers_thread) +{ + // Racy fast path: + // The race here should be OK since the race can only happen if + // another thread is writing to it with the lock held. In such case, + // we don't need to run pending finalizers since the writer thread + // will flush it. + if (to_finalize.len == 0) + return; + JL_LOCK_NOGC(&finalizers_lock); + if (to_finalize.len == 0) { + JL_UNLOCK_NOGC(&finalizers_lock); + return; + } + arraylist_t copied_list; + memcpy(&copied_list, &to_finalize, sizeof(copied_list)); + if (to_finalize.items == to_finalize._space) { + copied_list.items = copied_list._space; + } + jl_atomic_store_relaxed(&jl_gc_have_pending_finalizers, 0); + arraylist_new(&to_finalize, 0); + + uint64_t save_rngState[JL_RNG_SIZE]; + memcpy(&save_rngState[0], &ct->rngState[0], sizeof(save_rngState)); + jl_rng_split(ct->rngState, finalizer_rngState); + + // This releases the finalizers lock. + int8_t was_in_finalizer = ct->ptls->in_finalizer; + ct->ptls->in_finalizer = !finalizers_thread; + jl_gc_run_finalizers_in_list(ct, &copied_list); + ct->ptls->in_finalizer = was_in_finalizer; + arraylist_free(&copied_list); + + memcpy(&ct->rngState[0], &save_rngState[0], sizeof(save_rngState)); +} + +JL_DLLEXPORT void jl_gc_run_pending_finalizers(jl_task_t *ct) +{ + if (ct == NULL) + ct = jl_current_task; + jl_ptls_t ptls = ct->ptls; + if (!ptls->in_finalizer && ptls->locks.len == 0 && ptls->finalizers_inhibited == 0 && ptls->engine_nqueued == 0) { + run_finalizers(ct, 0); + } +} + +JL_DLLEXPORT int jl_gc_get_finalizers_inhibited(jl_ptls_t ptls) +{ + if (ptls == NULL) + ptls = jl_current_task->ptls; + return ptls->finalizers_inhibited; +} + +JL_DLLEXPORT void jl_gc_disable_finalizers_internal(void) +{ + jl_ptls_t ptls = jl_current_task->ptls; + ptls->finalizers_inhibited++; +} + +JL_DLLEXPORT void jl_gc_enable_finalizers_internal(void) +{ + jl_task_t *ct = jl_current_task; +#ifdef NDEBUG + ct->ptls->finalizers_inhibited--; +#else + jl_gc_enable_finalizers(ct, 1); +#endif +} + +JL_DLLEXPORT void jl_gc_enable_finalizers(jl_task_t *ct, int on) +{ + if (ct == NULL) + ct = jl_current_task; + jl_ptls_t ptls = ct->ptls; + int old_val = ptls->finalizers_inhibited; + int new_val = old_val + (on ? -1 : 1); + if (new_val < 0) { + JL_TRY { + jl_error(""); // get a backtrace + } + JL_CATCH { + jl_printf((JL_STREAM*)STDERR_FILENO, "WARNING: GC finalizers already enabled on this thread.\n"); + // Only print the backtrace once, to avoid spamming the logs + static int backtrace_printed = 0; + if (backtrace_printed == 0) { + backtrace_printed = 1; + jlbacktrace(); // written to STDERR_FILENO + } + } + return; + } + ptls->finalizers_inhibited = new_val; + if (jl_atomic_load_relaxed(&jl_gc_have_pending_finalizers)) { + jl_gc_run_pending_finalizers(ct); + } +} + +JL_DLLEXPORT int8_t jl_gc_is_in_finalizer(void) +{ + return jl_current_task->ptls->in_finalizer; +} + +static void schedule_all_finalizers(arraylist_t *flist) JL_NOTSAFEPOINT +{ + void **items = flist->items; + size_t len = flist->len; + for(size_t i = 0; i < len; i+=2) { + void *v = items[i]; + void *f = items[i + 1]; + if (__unlikely(!v)) + continue; + schedule_finalization(v, f); + } + flist->len = 0; +} + +void jl_gc_run_all_finalizers(jl_task_t *ct) +{ + int gc_n_threads; + jl_ptls_t* gc_all_tls_states; + gc_n_threads = jl_atomic_load_acquire(&jl_n_threads); + gc_all_tls_states = jl_atomic_load_relaxed(&jl_all_tls_states); + // this is called from `jl_atexit_hook`; threads could still be running + // so we have to guard the finalizers' lists + JL_LOCK_NOGC(&finalizers_lock); + schedule_all_finalizers(&finalizer_list_marked); + for (int i = 0; i < gc_n_threads; i++) { + jl_ptls_t ptls2 = gc_all_tls_states[i]; + if (ptls2 != NULL) + schedule_all_finalizers(&ptls2->finalizers); + } + // unlock here because `run_finalizers` locks this + JL_UNLOCK_NOGC(&finalizers_lock); + run_finalizers(ct, 1); +} + +void jl_gc_add_finalizer_(jl_ptls_t ptls, void *v, void *f) JL_NOTSAFEPOINT +{ + assert(jl_atomic_load_relaxed(&ptls->gc_state) == JL_GC_STATE_UNSAFE); + arraylist_t *a = &ptls->finalizers; + // This acquire load and the release store at the end are used to + // synchronize with `finalize_object` on another thread. Apart from the GC, + // which is blocked by entering a unsafe region, there might be only + // one other thread accessing our list in `finalize_object` + // (only one thread since it needs to acquire the finalizer lock). + // Similar to `finalize_object`, all content mutation has to be done + // between the acquire and the release of the length. + size_t oldlen = jl_atomic_load_acquire((_Atomic(size_t)*)&a->len); + if (__unlikely(oldlen + 2 > a->max)) { + JL_LOCK_NOGC(&finalizers_lock); + // `a->len` might have been modified. + // Another possibility is to always grow the array to `oldlen + 2` but + // it's simpler this way and uses slightly less memory =) + oldlen = a->len; + arraylist_grow(a, 2); + a->len = oldlen; + JL_UNLOCK_NOGC(&finalizers_lock); + } + void **items = a->items; + items[oldlen] = v; + items[oldlen + 1] = f; + jl_atomic_store_release((_Atomic(size_t)*)&a->len, oldlen + 2); +} + +JL_DLLEXPORT void jl_gc_add_ptr_finalizer(jl_ptls_t ptls, jl_value_t *v, void *f) JL_NOTSAFEPOINT +{ + jl_gc_add_finalizer_(ptls, (void*)(((uintptr_t)v) | 1), f); +} + +// schedule f(v) to call at the next quiescent interval (aka after the next safepoint/region on all threads) +JL_DLLEXPORT void jl_gc_add_quiescent(jl_ptls_t ptls, void **v, void *f) JL_NOTSAFEPOINT +{ + assert(!gc_ptr_tag(v, 3)); + jl_gc_add_finalizer_(ptls, (void*)(((uintptr_t)v) | 3), f); +} + +JL_DLLEXPORT void jl_gc_add_finalizer_th(jl_ptls_t ptls, jl_value_t *v, jl_function_t *f) JL_NOTSAFEPOINT +{ + if (__unlikely(jl_typetagis(f, jl_voidpointer_type))) { + jl_gc_add_ptr_finalizer(ptls, v, jl_unbox_voidpointer(f)); + } + else { + jl_gc_add_finalizer_(ptls, v, f); + } +} + +JL_DLLEXPORT void jl_gc_add_finalizer(jl_value_t *v, jl_function_t *f) +{ + jl_ptls_t ptls = jl_current_task->ptls; + jl_gc_add_finalizer_th(ptls, v, f); +} + +JL_DLLEXPORT void jl_finalize_th(jl_task_t *ct, jl_value_t *o) +{ + JL_LOCK_NOGC(&finalizers_lock); + // Copy the finalizers into a temporary list so that code in the finalizer + // won't change the list as we loop through them. + // This list is also used as the GC frame when we are running the finalizers + arraylist_t copied_list; + arraylist_new(&copied_list, 0); + // No need to check the to_finalize list since the user is apparently + // still holding a reference to the object + int gc_n_threads; + jl_ptls_t* gc_all_tls_states; + gc_n_threads = jl_atomic_load_acquire(&jl_n_threads); + gc_all_tls_states = jl_atomic_load_relaxed(&jl_all_tls_states); + for (int i = 0; i < gc_n_threads; i++) { + jl_ptls_t ptls2 = gc_all_tls_states[i]; + if (ptls2 != NULL) + finalize_object(&ptls2->finalizers, o, &copied_list, jl_atomic_load_relaxed(&ct->tid) != i); + } + finalize_object(&finalizer_list_marked, o, &copied_list, 0); + if (copied_list.len > 0) { + // This releases the finalizers lock. + jl_gc_run_finalizers_in_list(ct, &copied_list); + } + else { + JL_UNLOCK_NOGC(&finalizers_lock); + } + arraylist_free(&copied_list); +} + +JL_DLLEXPORT void jl_finalize(jl_value_t *o) +{ + jl_finalize_th(jl_current_task, o); +} + +// =========================================================================== // +// Threading +// =========================================================================== // + +int gc_n_threads; +jl_ptls_t* gc_all_tls_states; + +// =========================================================================== // +// MISC +// =========================================================================== // + +const uint64_t _jl_buff_tag[3] = {0x4eadc0004eadc000ull, 0x4eadc0004eadc000ull, 0x4eadc0004eadc000ull}; // aka 0xHEADER00 +JL_DLLEXPORT uintptr_t jl_get_buff_tag(void) JL_NOTSAFEPOINT +{ + return jl_buff_tag; +} + +// callback for passing OOM errors from gmp +JL_DLLEXPORT void jl_throw_out_of_memory_error(void) +{ + jl_throw(jl_memory_exception); +} + +#ifdef __cplusplus +} +#endif diff --git a/src/gc-common.h b/src/gc-common.h new file mode 100644 index 0000000000000..4d53830442a7d --- /dev/null +++ b/src/gc-common.h @@ -0,0 +1,176 @@ +// This file is a part of Julia. License is MIT: https://julialang.org/license + +#ifndef JL_GC_COMMON_H +#define JL_GC_COMMON_H + +#include "julia.h" +#include "julia_internal.h" +#ifndef _OS_WINDOWS_ +#include +#if defined(_OS_DARWIN_) && !defined(MAP_ANONYMOUS) +#define MAP_ANONYMOUS MAP_ANON +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +// =========================================================================== // +// GC Callbacks +// =========================================================================== // + +typedef void (*jl_gc_cb_func_t)(void); + +typedef struct _jl_gc_callback_list_t { + struct _jl_gc_callback_list_t *next; + jl_gc_cb_func_t func; +} jl_gc_callback_list_t; + +extern jl_gc_callback_list_t *gc_cblist_root_scanner; +extern jl_gc_callback_list_t *gc_cblist_task_scanner; +extern jl_gc_callback_list_t *gc_cblist_pre_gc; +extern jl_gc_callback_list_t *gc_cblist_post_gc; +extern jl_gc_callback_list_t *gc_cblist_notify_external_alloc; +extern jl_gc_callback_list_t *gc_cblist_notify_external_free; +extern jl_gc_callback_list_t *gc_cblist_notify_gc_pressure; + +#define gc_invoke_callbacks(ty, list, args) \ + do { \ + for (jl_gc_callback_list_t *cb = list; \ + cb != NULL; \ + cb = cb->next) \ + { \ + ((ty)(cb->func)) args; \ + } \ + } while (0) + +#ifdef __cplusplus +} +#endif + +// =========================================================================== // +// malloc wrappers, aligned allocation +// =========================================================================== // + +#if defined(_OS_WINDOWS_) +STATIC_INLINE void *jl_malloc_aligned(size_t sz, size_t align) +{ + return _aligned_malloc(sz ? sz : 1, align); +} +STATIC_INLINE void *jl_realloc_aligned(void *p, size_t sz, size_t oldsz, + size_t align) +{ + (void)oldsz; + return _aligned_realloc(p, sz ? sz : 1, align); +} +STATIC_INLINE void jl_free_aligned(void *p) JL_NOTSAFEPOINT +{ + _aligned_free(p); +} +#else +STATIC_INLINE void *jl_malloc_aligned(size_t sz, size_t align) +{ +#if defined(_P64) || defined(__APPLE__) + if (align <= 16) + return malloc(sz); +#endif + void *ptr; + if (posix_memalign(&ptr, align, sz)) + return NULL; + return ptr; +} +STATIC_INLINE void *jl_realloc_aligned(void *d, size_t sz, size_t oldsz, + size_t align) +{ +#if defined(_P64) || defined(__APPLE__) + if (align <= 16) + return realloc(d, sz); +#endif + void *b = jl_malloc_aligned(sz, align); + if (b != NULL) { + memcpy(b, d, oldsz > sz ? sz : oldsz); + free(d); + } + return b; +} +STATIC_INLINE void jl_free_aligned(void *p) JL_NOTSAFEPOINT +{ + free(p); +} +#endif +#define malloc_cache_align(sz) jl_malloc_aligned(sz, JL_CACHE_BYTE_ALIGNMENT) +#define realloc_cache_align(p, sz, oldsz) jl_realloc_aligned(p, sz, oldsz, JL_CACHE_BYTE_ALIGNMENT) + +// =========================================================================== // +// Pointer tagging +// =========================================================================== // + +STATIC_INLINE int gc_marked(uintptr_t bits) JL_NOTSAFEPOINT +{ + return (bits & GC_MARKED) != 0; +} + +STATIC_INLINE int gc_old(uintptr_t bits) JL_NOTSAFEPOINT +{ + return (bits & GC_OLD) != 0; +} + +STATIC_INLINE uintptr_t gc_set_bits(uintptr_t tag, int bits) JL_NOTSAFEPOINT +{ + return (tag & ~(uintptr_t)3) | bits; +} + +STATIC_INLINE uintptr_t gc_ptr_tag(void *v, uintptr_t mask) JL_NOTSAFEPOINT +{ + return ((uintptr_t)v) & mask; +} + +STATIC_INLINE void *gc_ptr_clear_tag(void *v, uintptr_t mask) JL_NOTSAFEPOINT +{ + return (void*)(((uintptr_t)v) & ~mask); +} + +// =========================================================================== // +// GC Metrics +// =========================================================================== // + +extern jl_gc_num_t gc_num; + +// =========================================================================== // +// Stop-the-world for GC +// =========================================================================== // +void jl_gc_wait_for_the_world(jl_ptls_t* gc_all_tls_states, int gc_n_threads); + +// =========================================================================== // +// Finalization +// =========================================================================== // + +// Protect all access to `finalizer_list_marked` and `to_finalize`. +// For accessing `ptls->finalizers`, the lock is needed if a thread +// is going to realloc the buffer (of its own list) or accessing the +// list of another thread +extern jl_mutex_t finalizers_lock; +// `ptls->finalizers` and `finalizer_list_marked` might have tagged pointers. +// If an object pointer has the lowest bit set, the next pointer is an unboxed c function pointer. +// If an object pointer has the second lowest bit set, the current pointer is a c object pointer. +// It must be aligned at least 4, and it finalized immediately (at "quiescence"). +// `to_finalize` should not have tagged pointers. +extern arraylist_t finalizer_list_marked; +extern arraylist_t to_finalize; + +void schedule_finalization(void *o, void *f) JL_NOTSAFEPOINT; +void run_finalizer(jl_task_t *ct, void *o, void *ff); +void run_finalizers(jl_task_t *ct, int finalizers_thread); +JL_DLLEXPORT void jl_gc_add_finalizer_th(jl_ptls_t ptls, jl_value_t *v, jl_function_t *f) JL_NOTSAFEPOINT; +JL_DLLEXPORT void jl_finalize_th(jl_task_t *ct, jl_value_t *o); + + +// =========================================================================== // +// Threading +// =========================================================================== // + +extern int gc_n_threads; +extern jl_ptls_t* gc_all_tls_states; + +#endif // JL_GC_COMMON_H diff --git a/src/gc-debug.c b/src/gc-debug.c index a7699cc3d0168..ec3c8d731edd8 100644 --- a/src/gc-debug.c +++ b/src/gc-debug.c @@ -1,6 +1,7 @@ // This file is a part of Julia. License is MIT: https://julialang.org/license -#include "gc.h" +#include "gc-common.h" +#include "gc-stock.h" #include "julia.h" #include #include diff --git a/src/gc-heap-snapshot.cpp b/src/gc-heap-snapshot.cpp index 77a6e70a127e6..b84d1f96f273c 100644 --- a/src/gc-heap-snapshot.cpp +++ b/src/gc-heap-snapshot.cpp @@ -2,9 +2,9 @@ #include "gc-heap-snapshot.h" +#include "julia.h" #include "julia_internal.h" #include "julia_assert.h" -#include "gc.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" @@ -183,7 +183,8 @@ struct HeapSnapshot { // when snapshotting is on. int gc_heap_snapshot_enabled = 0; HeapSnapshot *g_snapshot = nullptr; -extern jl_mutex_t heapsnapshot_lock; +// mutex for gc-heap-snapshot. +jl_mutex_t heapsnapshot_lock; void final_serialize_heap_snapshot(ios_t *json, ios_t *strings, HeapSnapshot &snapshot, char all_one); void serialize_heap_snapshot(ios_t *stream, HeapSnapshot &snapshot, char all_one); diff --git a/src/gc-heap-snapshot.h b/src/gc-heap-snapshot.h index 70884f5f62d6a..a58f58aba5458 100644 --- a/src/gc-heap-snapshot.h +++ b/src/gc-heap-snapshot.h @@ -35,6 +35,7 @@ void _gc_heap_snapshot_record_finlist(jl_value_t *finlist, size_t index) JL_NOTS extern int gc_heap_snapshot_enabled; extern int prev_sweep_full; +extern jl_mutex_t heapsnapshot_lock; int gc_slot_to_fieldidx(void *_obj, void *slot, jl_datatype_t *vt) JL_NOTSAFEPOINT; int gc_slot_to_arrayidx(void *_obj, void *begin) JL_NOTSAFEPOINT; diff --git a/src/gc-interface.h b/src/gc-interface.h new file mode 100644 index 0000000000000..201c5f6e1741e --- /dev/null +++ b/src/gc-interface.h @@ -0,0 +1,248 @@ +// This file is a part of Julia. License is MIT: https://julialang.org/license + +/* + Garbage Collection interface that must be implemented by third-party GCs +*/ + +#ifndef JL_GC_INTERFACE_H +#define JL_GC_INTERFACE_H + +#include "dtypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct _jl_tls_states_t; +struct _jl_value_t; +struct _jl_weakref_t; +struct _jl_datatype_t; + +// ========================================================================= // +// GC Metrics +// ========================================================================= // + +// This struct must be kept in sync with the Julia type of the same name in base/timing.jl +typedef struct { + int64_t allocd; + int64_t deferred_alloc; + int64_t freed; + uint64_t malloc; + uint64_t realloc; + uint64_t poolalloc; + uint64_t bigalloc; + uint64_t freecall; + uint64_t total_time; + uint64_t total_allocd; + size_t interval; + int pause; + int full_sweep; + uint64_t max_pause; + uint64_t max_memory; + uint64_t time_to_safepoint; + uint64_t max_time_to_safepoint; + uint64_t total_time_to_safepoint; + uint64_t sweep_time; + uint64_t mark_time; + uint64_t total_sweep_time; + uint64_t total_mark_time; + uint64_t last_full_sweep; + uint64_t last_incremental_sweep; +} jl_gc_num_t; + +// ========================================================================= // +// System-wide Initialization +// ========================================================================= // + +// System-wide initialization function. Responsible for initializing global locks as well as +// global memory parameters (e.g. target heap size) used by the collector. +void jl_gc_init(void); +// Spawns GC threads. +void jl_start_gc_threads(void); + +// ========================================================================= // +// Per-thread Initialization +// ========================================================================= // + +// Initializes thread-local data structures such as thread-local object pools, +// thread-local remembered sets and thread-local allocation counters. +// Should be called exactly once per Julia thread. +void jl_init_thread_heap(struct _jl_tls_states_t *ptls) JL_NOTSAFEPOINT; +// Deallocates any memory previously used for thread-local GC data structures. +// Mostly used to ensure that we perform this memory cleanup for foreign threads that are +// about to leave Julia. +void jl_free_thread_gc_state(struct _jl_tls_states_t *ptls); + +// ========================================================================= // +// Controls +// ========================================================================= // + +typedef enum { + JL_GC_AUTO = 0, // use heuristics to determine the collection type + JL_GC_FULL = 1, // force a full collection + JL_GC_INCREMENTAL = 2, // force an incremental collection +} jl_gc_collection_t; +// Enables or disables (depending on the value of the argument) the collector. Returns +// whether GC was previously enabled. +JL_DLLEXPORT int jl_gc_enable(int on); +// Returns whether the collector is enabled. +JL_DLLEXPORT int jl_gc_is_enabled(void); +// Sets a soft limit to Julia's heap. +JL_DLLEXPORT void jl_gc_set_max_memory(uint64_t max_mem); +// Runs a GC cycle. This function's parameter determines whether we're running an +// incremental, full, or automatic (i.e. heuristic driven) collection. Returns whether we +// should run a collection cycle again (e.g. a full mark right after a full sweep to ensure +// we do a full heap traversal). +JL_DLLEXPORT void jl_gc_collect(jl_gc_collection_t collection); + +// ========================================================================= // +// Metrics +// ========================================================================= // + +// Retrieves Julia's `GC_Num` (structure that stores GC statistics). +JL_DLLEXPORT jl_gc_num_t jl_gc_num(void); +// Returns the difference between the current value of total live bytes now +// (live bytes at the last collection plus number of bytes allocated since then), +// compared to the value at the last time this function was called. +JL_DLLEXPORT int64_t jl_gc_diff_total_bytes(void) JL_NOTSAFEPOINT; +// Returns the difference between the current value of total live bytes now +// (live bytes at the last collection plus number of bytes allocated since then) +// compared to the value at the last time this function was called. The offset parameter +// is subtracted from this value in order to obtain the return value. +JL_DLLEXPORT int64_t jl_gc_sync_total_bytes(int64_t offset) JL_NOTSAFEPOINT; +// Returns the number of pool allocated bytes. This could always return 0 for GC +// implementations that do not use pools. +JL_DLLEXPORT int64_t jl_gc_pool_live_bytes(void); +// Returns the number of live bytes at the end of the last collection cycle +// (doesn't include the number of allocated bytes since then). +JL_DLLEXPORT int64_t jl_gc_live_bytes(void); +// Stores the number of live bytes at the end of the last collection cycle plus the number +// of bytes we allocated since then into the 64-bit integer pointer passed as an argument. +JL_DLLEXPORT void jl_gc_get_total_bytes(int64_t *bytes) JL_NOTSAFEPOINT; +// Retrieves the value of Julia's soft heap limit. +JL_DLLEXPORT uint64_t jl_gc_get_max_memory(void); +// High-resolution (nano-seconds) value of total time spent in GC. +JL_DLLEXPORT uint64_t jl_gc_total_hrtime(void); + +// ========================================================================= // +// Allocation +// ========================================================================= // + +// Allocates small objects and increments Julia allocation counterst. Size of the object +// header must be included in the object size. The (possibly unused in some implementations) +// offset to the arena in which we're allocating is passed in the second parameter, and the +// object size in the third parameter. If thread-local allocators are used, then this +// function should allocate in the thread-local allocator of the thread referenced by the +// jl_ptls_t argument. An additional (last) parameter containing information about the type +// of the object being allocated may be used to record an allocation of that type in the +// allocation profiler. +JL_DLLEXPORT struct _jl_value_t *jl_gc_small_alloc(struct _jl_tls_states_t *ptls, + int offset, int osize, + struct _jl_value_t *type); +// Description: Allocates large objects and increments Julia allocation counters. Size of +// the object header must be included in the object size. If thread-local allocators are +// used, then this function should allocate in the thread-local allocator of the thread +// referenced by the jl_ptls_t argument. An additional (last) parameter containing +// information about the type of the object being allocated may be used to record an +// allocation of that type in the allocation profiler. +JL_DLLEXPORT struct _jl_value_t *jl_gc_big_alloc(struct _jl_tls_states_t *ptls, size_t sz, + struct _jl_value_t *type); +// Wrapper around Libc malloc that updates Julia allocation counters. +JL_DLLEXPORT void *jl_gc_counted_malloc(size_t sz); +// Wrapper around Libc calloc that updates Julia allocation counters. +JL_DLLEXPORT void *jl_gc_counted_calloc(size_t nm, size_t sz); +// Wrapper around Libc free that updates Julia allocation counters. +JL_DLLEXPORT void jl_gc_counted_free_with_size(void *p, size_t sz); +// Wrapper around Libc realloc that updates Julia allocation counters. +JL_DLLEXPORT void *jl_gc_counted_realloc_with_old_size(void *p, size_t old, size_t sz); +// Wrapper around Libc malloc that allocates a memory region with a few additional machine +// words before the actual payload that are used to record the size of the requested +// allocation. Also updates Julia allocation counters. The function returns a pointer to the +// payload as a result of the allocation. +JL_DLLEXPORT void *jl_malloc(size_t sz); +// Wrapper around Libc calloc that allocates a memory region with a few additional machine +// words before the actual payload that are used to record the size of the requested +// allocation. Also updates Julia allocation counters. The function returns a pointer to the +// payload as a result of the allocation. +JL_DLLEXPORT void *jl_calloc(size_t nm, size_t sz); +// Wrapper around Libc free that takes a pointer to the payload of a memory region allocated +// with jl_malloc or jl_calloc, and uses the size information stored in the first machine +// words of the memory buffer update Julia allocation counters, and then frees the +// corresponding memory buffer. +JL_DLLEXPORT void jl_free(void *p); +// Wrapper around Libc realloc that takes a memory region allocated with jl_malloc or +// jl_calloc, and uses the size information stored in the first machine words of the memory +// buffer to update Julia allocation counters, reallocating the corresponding memory buffer +// in the end. +JL_DLLEXPORT void *jl_realloc(void *p, size_t sz); +// Wrapper around Libc malloc that's used to dynamically allocate memory for Arrays and +// Strings. It increments Julia allocation counters and should check whether we're close to +// the Julia heap target, and therefore, whether we should run a collection. Note that this +// doesn't record the size of the allocation request in a side metadata (i.e. a few words in +// front of the memory payload): this function is used for Julia object allocations, and we +// assume that there is already a field in the Julia object being allocated that we may use +// to store the size of the memory buffer. +JL_DLLEXPORT void *jl_gc_managed_malloc(size_t sz); +// Allocates a new weak-reference, assigns its value and increments Julia allocation +// counters. If thread-local allocators are used, then this function should allocate in the +// thread-local allocator of the thread referenced by the first jl_ptls_t argument. +JL_DLLEXPORT struct _jl_weakref_t *jl_gc_new_weakref_th(struct _jl_tls_states_t *ptls, + struct _jl_value_t *value); +// Allocates a new weak-reference, assigns its value and increments Julia allocation +// counters. If thread-local allocators are used, then this function should allocate in the +// thread-local allocator of the current thread. +JL_DLLEXPORT struct _jl_weakref_t *jl_gc_new_weakref(struct _jl_value_t *value); +// Allocates an object whose size is specified by the function argument and increments Julia +// allocation counters. If thread-local allocators are used, then this function should +// allocate in the thread-local allocator of the current thread. +JL_DLLEXPORT struct _jl_value_t *jl_gc_allocobj(size_t sz); +// Permanently allocates a memory slot of the size specified by the first parameter. This +// block of memory is allocated in an immortal region that is never swept. The second +// parameter specifies whether the memory should be filled with zeros. The third and fourth +// parameters specify the alignment and an offset in bytes, respectively. Specifically, the +// pointer obtained by advancing the result of this function by the number of bytes +// specified in the fourth parameter will be aligned according to the value given by the +// third parameter in bytes. +JL_DLLEXPORT void *jl_gc_perm_alloc(size_t sz, int zero, unsigned align, + unsigned offset) JL_NOTSAFEPOINT; +// Permanently allocates an object of the size specified by the first parameter. Size of the +// object header must be included in the object size. This object is allocated in an +// immortal region that is never swept. The second parameter specifies the type of the +// object being allocated and will be used to set the object header. +struct _jl_value_t *jl_gc_permobj(size_t sz, void *ty) JL_NOTSAFEPOINT; + +// ========================================================================= // +// Runtime Write-Barriers +// ========================================================================= // + +// Write barrier slow-path. If a generational collector is used, +// it may enqueue an old object into the remembered set of the calling thread. +JL_DLLEXPORT void jl_gc_queue_root(const struct _jl_value_t *ptr) JL_NOTSAFEPOINT; +// In a generational collector is used, this function walks over the fields of the +// object specified by the second parameter (as defined by the data type in the third +// parameter). If a field points to a young object, the first parameter is enqueued into the +// remembered set of the calling thread. +JL_DLLEXPORT void jl_gc_queue_multiroot(const struct _jl_value_t *root, const void *stored, + struct _jl_datatype_t *dt) JL_NOTSAFEPOINT; +// If a generational collector is used, checks whether the function argument points to an +// old object, and if so, calls the write barrier slow path above. In most cases, this +// function is used when its caller has verified that there is a young reference in the +// object that's being passed as an argument to this function. +STATIC_INLINE void jl_gc_wb_back(const void *ptr) JL_NOTSAFEPOINT; +// Write barrier function that must be used after pointer writes to heap-allocated objects – +// the value of the field being written must also point to a heap-allocated object. +// If a generational collector is used, it may check whether the two function arguments are +// in different GC generations (i.e. if the first argument points to an old object and the +// second argument points to a young object), and if so, call the write barrier slow-path. +STATIC_INLINE void jl_gc_wb(const void *parent, const void *ptr) JL_NOTSAFEPOINT; +// Write-barrier function that must be used after copying multiple fields of an object into +// another. It should be semantically equivalent to triggering multiple write barriers – one +// per field of the object being copied, but may be special-cased for performance reasons. +STATIC_INLINE void jl_gc_multi_wb(const void *parent, + const struct _jl_value_t *ptr) JL_NOTSAFEPOINT; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/gc-page-profiler.c b/src/gc-page-profiler.c index 2e876e4b7b4d6..2625fa812781a 100644 --- a/src/gc-page-profiler.c +++ b/src/gc-page-profiler.c @@ -1,6 +1,7 @@ // This file is a part of Julia. License is MIT: https://julialang.org/license #include "gc-page-profiler.h" +#include "julia.h" #ifdef __cplusplus extern "C" { diff --git a/src/gc-page-profiler.h b/src/gc-page-profiler.h index 28989f8f8e206..0dd72ad072fa9 100644 --- a/src/gc-page-profiler.h +++ b/src/gc-page-profiler.h @@ -3,7 +3,7 @@ #ifndef GC_PAGE_PROFILER_H #define GC_PAGE_PROFILER_H -#include "gc.h" +#include "gc-stock.h" #ifdef __cplusplus extern "C" { diff --git a/src/gc-pages.c b/src/gc-pages.c index 698cf84c3cfb6..71d59de29166f 100644 --- a/src/gc-pages.c +++ b/src/gc-pages.c @@ -1,6 +1,7 @@ // This file is a part of Julia. License is MIT: https://julialang.org/license -#include "gc.h" +#include "gc-common.h" +#include "gc-stock.h" #ifndef _OS_WINDOWS_ # include #endif @@ -9,6 +10,8 @@ extern "C" { #endif +uv_mutex_t gc_pages_lock; + JL_DLLEXPORT uint64_t jl_get_pg_size(void) { return GC_PAGE_SZ; @@ -67,7 +70,7 @@ char *jl_gc_try_alloc_pages_(int pg_cnt) JL_NOTSAFEPOINT // more chunks (or other allocations). The final page count is recorded // and will be used as the starting count next time. If the page count is // smaller `MIN_BLOCK_PG_ALLOC` a `jl_memory_exception` is thrown. -// Assumes `gc_perm_lock` is acquired, the lock is released before the +// Assumes `gc_pages_lock` is acquired, the lock is released before the // exception is thrown. char *jl_gc_try_alloc_pages(void) JL_NOTSAFEPOINT { @@ -87,7 +90,7 @@ char *jl_gc_try_alloc_pages(void) JL_NOTSAFEPOINT block_pg_cnt = pg_cnt = min_block_pg_alloc; } else { - uv_mutex_unlock(&gc_perm_lock); + uv_mutex_unlock(&gc_pages_lock); jl_throw(jl_memory_exception); } } @@ -127,11 +130,11 @@ NOINLINE jl_gc_pagemeta_t *jl_gc_alloc_page(void) JL_NOTSAFEPOINT goto exit; } - uv_mutex_lock(&gc_perm_lock); + uv_mutex_lock(&gc_pages_lock); // another thread may have allocated a large block while we were waiting... meta = pop_lf_back(&global_page_pool_clean); if (meta != NULL) { - uv_mutex_unlock(&gc_perm_lock); + uv_mutex_unlock(&gc_pages_lock); gc_alloc_map_set(meta->data, GC_PAGE_ALLOCATED); goto exit; } @@ -149,7 +152,7 @@ NOINLINE jl_gc_pagemeta_t *jl_gc_alloc_page(void) JL_NOTSAFEPOINT push_lf_back(&global_page_pool_clean, pg); } } - uv_mutex_unlock(&gc_perm_lock); + uv_mutex_unlock(&gc_pages_lock); exit: #ifdef _OS_WINDOWS_ VirtualAlloc(meta->data, GC_PAGE_SZ, MEM_COMMIT, PAGE_READWRITE); diff --git a/src/gc-stacks.c b/src/gc-stacks.c index 2f6075b56b8ef..5706f4ce67c1d 100644 --- a/src/gc-stacks.c +++ b/src/gc-stacks.c @@ -1,6 +1,7 @@ // This file is a part of Julia. License is MIT: https://julialang.org/license -#include "gc.h" +#include "gc-common.h" +#include "threading.h" #ifndef _OS_WINDOWS_ # include #endif diff --git a/src/gc.c b/src/gc-stock.c similarity index 89% rename from src/gc.c rename to src/gc-stock.c index 9f57bf3c6b944..1fc2087da6503 100644 --- a/src/gc.c +++ b/src/gc-stock.c @@ -1,6 +1,9 @@ // This file is a part of Julia. License is MIT: https://julialang.org/license -#include "gc.h" +#include "gc-common.h" +#include "gc-stock.h" +#include "gc-alloc-profiler.h" +#include "gc-heap-snapshot.h" #include "gc-page-profiler.h" #include "julia.h" #include "julia_atomics.h" @@ -38,125 +41,6 @@ uv_mutex_t gc_queue_observer_lock; // Tag for sentinel nodes in bigval list uintptr_t gc_bigval_sentinel_tag; -// Linked list of callback functions - -typedef void (*jl_gc_cb_func_t)(void); - -typedef struct jl_gc_callback_list_t { - struct jl_gc_callback_list_t *next; - jl_gc_cb_func_t func; -} jl_gc_callback_list_t; - -static jl_gc_callback_list_t *gc_cblist_root_scanner; -static jl_gc_callback_list_t *gc_cblist_task_scanner; -static jl_gc_callback_list_t *gc_cblist_pre_gc; -static jl_gc_callback_list_t *gc_cblist_post_gc; -static jl_gc_callback_list_t *gc_cblist_notify_external_alloc; -static jl_gc_callback_list_t *gc_cblist_notify_external_free; -static jl_gc_callback_list_t *gc_cblist_notify_gc_pressure; - -#define gc_invoke_callbacks(ty, list, args) \ - do { \ - for (jl_gc_callback_list_t *cb = list; \ - cb != NULL; \ - cb = cb->next) \ - { \ - ((ty)(cb->func)) args; \ - } \ - } while (0) - -static void jl_gc_register_callback(jl_gc_callback_list_t **list, - jl_gc_cb_func_t func) -{ - while (*list != NULL) { - if ((*list)->func == func) - return; - list = &((*list)->next); - } - *list = (jl_gc_callback_list_t *)malloc_s(sizeof(jl_gc_callback_list_t)); - (*list)->next = NULL; - (*list)->func = func; -} - -static void jl_gc_deregister_callback(jl_gc_callback_list_t **list, - jl_gc_cb_func_t func) -{ - while (*list != NULL) { - if ((*list)->func == func) { - jl_gc_callback_list_t *tmp = *list; - (*list) = (*list)->next; - free(tmp); - return; - } - list = &((*list)->next); - } -} - -JL_DLLEXPORT void jl_gc_set_cb_root_scanner(jl_gc_cb_root_scanner_t cb, int enable) -{ - if (enable) - jl_gc_register_callback(&gc_cblist_root_scanner, (jl_gc_cb_func_t)cb); - else - jl_gc_deregister_callback(&gc_cblist_root_scanner, (jl_gc_cb_func_t)cb); -} - -JL_DLLEXPORT void jl_gc_set_cb_task_scanner(jl_gc_cb_task_scanner_t cb, int enable) -{ - if (enable) - jl_gc_register_callback(&gc_cblist_task_scanner, (jl_gc_cb_func_t)cb); - else - jl_gc_deregister_callback(&gc_cblist_task_scanner, (jl_gc_cb_func_t)cb); -} - -JL_DLLEXPORT void jl_gc_set_cb_pre_gc(jl_gc_cb_pre_gc_t cb, int enable) -{ - if (enable) - jl_gc_register_callback(&gc_cblist_pre_gc, (jl_gc_cb_func_t)cb); - else - jl_gc_deregister_callback(&gc_cblist_pre_gc, (jl_gc_cb_func_t)cb); -} - -JL_DLLEXPORT void jl_gc_set_cb_post_gc(jl_gc_cb_post_gc_t cb, int enable) -{ - if (enable) - jl_gc_register_callback(&gc_cblist_post_gc, (jl_gc_cb_func_t)cb); - else - jl_gc_deregister_callback(&gc_cblist_post_gc, (jl_gc_cb_func_t)cb); -} - -JL_DLLEXPORT void jl_gc_set_cb_notify_external_alloc(jl_gc_cb_notify_external_alloc_t cb, int enable) -{ - if (enable) - jl_gc_register_callback(&gc_cblist_notify_external_alloc, (jl_gc_cb_func_t)cb); - else - jl_gc_deregister_callback(&gc_cblist_notify_external_alloc, (jl_gc_cb_func_t)cb); -} - -JL_DLLEXPORT void jl_gc_set_cb_notify_external_free(jl_gc_cb_notify_external_free_t cb, int enable) -{ - if (enable) - jl_gc_register_callback(&gc_cblist_notify_external_free, (jl_gc_cb_func_t)cb); - else - jl_gc_deregister_callback(&gc_cblist_notify_external_free, (jl_gc_cb_func_t)cb); -} - -JL_DLLEXPORT void jl_gc_set_cb_notify_gc_pressure(jl_gc_cb_notify_gc_pressure_t cb, int enable) -{ - if (enable) - jl_gc_register_callback(&gc_cblist_notify_gc_pressure, (jl_gc_cb_func_t)cb); - else - jl_gc_deregister_callback(&gc_cblist_notify_gc_pressure, (jl_gc_cb_func_t)cb); -} - -// Protect all access to `finalizer_list_marked` and `to_finalize`. -// For accessing `ptls->finalizers`, the lock is needed if a thread -// is going to realloc the buffer (of its own list) or accessing the -// list of another thread -static jl_mutex_t finalizers_lock; - -// mutex for gc-heap-snapshot. -jl_mutex_t heapsnapshot_lock; - // Flag that tells us whether we need to support conservative marking // of objects. static _Atomic(int) support_conservative_marking = 0; @@ -193,406 +77,11 @@ static _Atomic(int) support_conservative_marking = 0; * finalizers in unmanaged (GC safe) mode. */ -jl_gc_num_t gc_num = {0}; -static size_t last_long_collect_interval; -int gc_n_threads; -jl_ptls_t* gc_all_tls_states; gc_heapstatus_t gc_heap_stats = {0}; -int next_sweep_full = 0; -const uint64_t _jl_buff_tag[3] = {0x4eadc0004eadc000ull, 0x4eadc0004eadc000ull, 0x4eadc0004eadc000ull}; // aka 0xHEADER00 -JL_DLLEXPORT uintptr_t jl_get_buff_tag(void) JL_NOTSAFEPOINT -{ - return jl_buff_tag; -} // List of big objects in oldest generation (`GC_OLD_MARKED`). Not per-thread. Accessed only by master thread. bigval_t *oldest_generation_of_bigvals = NULL; -// -- Finalization -- -// `ptls->finalizers` and `finalizer_list_marked` might have tagged pointers. -// If an object pointer has the lowest bit set, the next pointer is an unboxed c function pointer. -// If an object pointer has the second lowest bit set, the current pointer is a c object pointer. -// It must be aligned at least 4, and it finalized immediately (at "quiescence"). -// `to_finalize` should not have tagged pointers. -arraylist_t finalizer_list_marked; -arraylist_t to_finalize; -JL_DLLEXPORT _Atomic(int) jl_gc_have_pending_finalizers = 0; - -void jl_gc_wait_for_the_world(jl_ptls_t* gc_all_tls_states, int gc_n_threads); - -// malloc wrappers, aligned allocation - -#if defined(_OS_WINDOWS_) -STATIC_INLINE void *jl_malloc_aligned(size_t sz, size_t align) -{ - return _aligned_malloc(sz ? sz : 1, align); -} -STATIC_INLINE void jl_free_aligned(void *p) JL_NOTSAFEPOINT -{ - _aligned_free(p); -} -#else -STATIC_INLINE void *jl_malloc_aligned(size_t sz, size_t align) -{ -#if defined(_P64) || defined(__APPLE__) - if (align <= 16) - return malloc(sz); -#endif - void *ptr; - if (posix_memalign(&ptr, align, sz)) - return NULL; - return ptr; -} -STATIC_INLINE void jl_free_aligned(void *p) JL_NOTSAFEPOINT -{ - free(p); -} -#endif -#define malloc_cache_align(sz) jl_malloc_aligned(sz, JL_CACHE_BYTE_ALIGNMENT) - -static void schedule_finalization(void *o, void *f) JL_NOTSAFEPOINT -{ - arraylist_push(&to_finalize, o); - arraylist_push(&to_finalize, f); - // doesn't need release, since we'll keep checking (on the reader) until we see the work and - // release our lock, and that will have a release barrier by then - jl_atomic_store_relaxed(&jl_gc_have_pending_finalizers, 1); -} - -static void run_finalizer(jl_task_t *ct, void *o, void *ff) -{ - int ptr_finalizer = gc_ptr_tag(o, 1); - o = gc_ptr_clear_tag(o, 3); - if (ptr_finalizer) { - ((void (*)(void*))ff)((void*)o); - return; - } - JL_TRY { - size_t last_age = ct->world_age; - ct->world_age = jl_atomic_load_acquire(&jl_world_counter); - jl_apply_generic((jl_value_t*)ff, (jl_value_t**)&o, 1); - ct->world_age = last_age; - } - JL_CATCH { - jl_printf((JL_STREAM*)STDERR_FILENO, "error in running finalizer: "); - jl_static_show((JL_STREAM*)STDERR_FILENO, jl_current_exception(ct)); - jl_printf((JL_STREAM*)STDERR_FILENO, "\n"); - jlbacktrace(); // written to STDERR_FILENO - } -} - -// if `need_sync` is true, the `list` is the `finalizers` list of another -// thread and we need additional synchronizations -static void finalize_object(arraylist_t *list, jl_value_t *o, - arraylist_t *copied_list, int need_sync) JL_NOTSAFEPOINT -{ - // The acquire load makes sure that the first `len` objects are valid. - // If `need_sync` is true, all mutations of the content should be limited - // to the first `oldlen` elements and no mutation is allowed after the - // new length is published with the `cmpxchg` at the end of the function. - // This way, the mutation should not conflict with the owning thread, - // which only writes to locations later than `len` - // and will not resize the buffer without acquiring the lock. - size_t len = need_sync ? jl_atomic_load_acquire((_Atomic(size_t)*)&list->len) : list->len; - size_t oldlen = len; - void **items = list->items; - size_t j = 0; - for (size_t i = 0; i < len; i += 2) { - void *v = items[i]; - int move = 0; - if (o == (jl_value_t*)gc_ptr_clear_tag(v, 1)) { - void *f = items[i + 1]; - move = 1; - arraylist_push(copied_list, v); - arraylist_push(copied_list, f); - } - if (move || __unlikely(!v)) { - // remove item - } - else { - if (j < i) { - items[j] = items[i]; - items[j+1] = items[i+1]; - } - j += 2; - } - } - len = j; - if (oldlen == len) - return; - if (need_sync) { - // The memset needs to be unconditional since the thread might have - // already read the length. - // The `memset` (like any other content mutation) has to be done - // **before** the `cmpxchg` which publishes the length. - memset(&items[len], 0, (oldlen - len) * sizeof(void*)); - jl_atomic_cmpswap((_Atomic(size_t)*)&list->len, &oldlen, len); - } - else { - list->len = len; - } -} - -// The first two entries are assumed to be empty and the rest are assumed to -// be pointers to `jl_value_t` objects -static void jl_gc_push_arraylist(jl_task_t *ct, arraylist_t *list) JL_NOTSAFEPOINT -{ - void **items = list->items; - items[0] = (void*)JL_GC_ENCODE_PUSHARGS(list->len - 2); - items[1] = ct->gcstack; - ct->gcstack = (jl_gcframe_t*)items; -} - -// Same assumption as `jl_gc_push_arraylist`. Requires the finalizers lock -// to be hold for the current thread and will release the lock when the -// function returns. -static void jl_gc_run_finalizers_in_list(jl_task_t *ct, arraylist_t *list) JL_NOTSAFEPOINT_LEAVE -{ - // Avoid marking `ct` as non-migratable via an `@async` task (as noted in the docstring - // of `finalizer`) in a finalizer: - uint8_t sticky = ct->sticky; - // empty out the first two entries for the GC frame - arraylist_push(list, list->items[0]); - arraylist_push(list, list->items[1]); - jl_gc_push_arraylist(ct, list); - void **items = list->items; - size_t len = list->len; - JL_UNLOCK_NOGC(&finalizers_lock); - // run finalizers in reverse order they were added, so lower-level finalizers run last - for (size_t i = len-4; i >= 2; i -= 2) - run_finalizer(ct, items[i], items[i + 1]); - // first entries were moved last to make room for GC frame metadata - run_finalizer(ct, items[len-2], items[len-1]); - // matches the jl_gc_push_arraylist above - JL_GC_POP(); - ct->sticky = sticky; -} - -static uint64_t finalizer_rngState[JL_RNG_SIZE]; - -void jl_rng_split(uint64_t dst[JL_RNG_SIZE], uint64_t src[JL_RNG_SIZE]) JL_NOTSAFEPOINT; - -JL_DLLEXPORT void jl_gc_init_finalizer_rng_state(void) -{ - jl_rng_split(finalizer_rngState, jl_current_task->rngState); -} - -static void run_finalizers(jl_task_t *ct, int finalizers_thread) -{ - // Racy fast path: - // The race here should be OK since the race can only happen if - // another thread is writing to it with the lock held. In such case, - // we don't need to run pending finalizers since the writer thread - // will flush it. - if (to_finalize.len == 0) - return; - JL_LOCK_NOGC(&finalizers_lock); - if (to_finalize.len == 0) { - JL_UNLOCK_NOGC(&finalizers_lock); - return; - } - arraylist_t copied_list; - memcpy(&copied_list, &to_finalize, sizeof(copied_list)); - if (to_finalize.items == to_finalize._space) { - copied_list.items = copied_list._space; - } - jl_atomic_store_relaxed(&jl_gc_have_pending_finalizers, 0); - arraylist_new(&to_finalize, 0); - - uint64_t save_rngState[JL_RNG_SIZE]; - memcpy(&save_rngState[0], &ct->rngState[0], sizeof(save_rngState)); - jl_rng_split(ct->rngState, finalizer_rngState); - - // This releases the finalizers lock. - int8_t was_in_finalizer = ct->ptls->in_finalizer; - ct->ptls->in_finalizer = !finalizers_thread; - jl_gc_run_finalizers_in_list(ct, &copied_list); - ct->ptls->in_finalizer = was_in_finalizer; - arraylist_free(&copied_list); - - memcpy(&ct->rngState[0], &save_rngState[0], sizeof(save_rngState)); -} - -JL_DLLEXPORT void jl_gc_run_pending_finalizers(jl_task_t *ct) -{ - if (ct == NULL) - ct = jl_current_task; - jl_ptls_t ptls = ct->ptls; - if (!ptls->in_finalizer && ptls->locks.len == 0 && ptls->finalizers_inhibited == 0 && ptls->engine_nqueued == 0) { - run_finalizers(ct, 0); - } -} - -JL_DLLEXPORT int jl_gc_get_finalizers_inhibited(jl_ptls_t ptls) -{ - if (ptls == NULL) - ptls = jl_current_task->ptls; - return ptls->finalizers_inhibited; -} - -JL_DLLEXPORT void jl_gc_disable_finalizers_internal(void) -{ - jl_ptls_t ptls = jl_current_task->ptls; - ptls->finalizers_inhibited++; -} - -JL_DLLEXPORT void jl_gc_enable_finalizers_internal(void) -{ - jl_task_t *ct = jl_current_task; -#ifdef NDEBUG - ct->ptls->finalizers_inhibited--; -#else - jl_gc_enable_finalizers(ct, 1); -#endif -} - -JL_DLLEXPORT void jl_gc_enable_finalizers(jl_task_t *ct, int on) -{ - if (ct == NULL) - ct = jl_current_task; - jl_ptls_t ptls = ct->ptls; - int old_val = ptls->finalizers_inhibited; - int new_val = old_val + (on ? -1 : 1); - if (new_val < 0) { - JL_TRY { - jl_error(""); // get a backtrace - } - JL_CATCH { - jl_printf((JL_STREAM*)STDERR_FILENO, "WARNING: GC finalizers already enabled on this thread.\n"); - // Only print the backtrace once, to avoid spamming the logs - static int backtrace_printed = 0; - if (backtrace_printed == 0) { - backtrace_printed = 1; - jlbacktrace(); // written to STDERR_FILENO - } - } - return; - } - ptls->finalizers_inhibited = new_val; - if (jl_atomic_load_relaxed(&jl_gc_have_pending_finalizers)) { - jl_gc_run_pending_finalizers(ct); - } -} - -JL_DLLEXPORT int8_t jl_gc_is_in_finalizer(void) -{ - return jl_current_task->ptls->in_finalizer; -} - -static void schedule_all_finalizers(arraylist_t *flist) JL_NOTSAFEPOINT -{ - void **items = flist->items; - size_t len = flist->len; - for(size_t i = 0; i < len; i+=2) { - void *v = items[i]; - void *f = items[i + 1]; - if (__unlikely(!v)) - continue; - schedule_finalization(v, f); - } - flist->len = 0; -} - -void jl_gc_run_all_finalizers(jl_task_t *ct) -{ - int gc_n_threads; - jl_ptls_t* gc_all_tls_states; - gc_n_threads = jl_atomic_load_acquire(&jl_n_threads); - gc_all_tls_states = jl_atomic_load_relaxed(&jl_all_tls_states); - // this is called from `jl_atexit_hook`; threads could still be running - // so we have to guard the finalizers' lists - JL_LOCK_NOGC(&finalizers_lock); - schedule_all_finalizers(&finalizer_list_marked); - for (int i = 0; i < gc_n_threads; i++) { - jl_ptls_t ptls2 = gc_all_tls_states[i]; - if (ptls2 != NULL) - schedule_all_finalizers(&ptls2->finalizers); - } - // unlock here because `run_finalizers` locks this - JL_UNLOCK_NOGC(&finalizers_lock); - run_finalizers(ct, 1); -} - -void jl_gc_add_finalizer_(jl_ptls_t ptls, void *v, void *f) JL_NOTSAFEPOINT -{ - assert(jl_atomic_load_relaxed(&ptls->gc_state) == JL_GC_STATE_UNSAFE); - arraylist_t *a = &ptls->finalizers; - // This acquire load and the release store at the end are used to - // synchronize with `finalize_object` on another thread. Apart from the GC, - // which is blocked by entering a unsafe region, there might be only - // one other thread accessing our list in `finalize_object` - // (only one thread since it needs to acquire the finalizer lock). - // Similar to `finalize_object`, all content mutation has to be done - // between the acquire and the release of the length. - size_t oldlen = jl_atomic_load_acquire((_Atomic(size_t)*)&a->len); - if (__unlikely(oldlen + 2 > a->max)) { - JL_LOCK_NOGC(&finalizers_lock); - // `a->len` might have been modified. - // Another possibility is to always grow the array to `oldlen + 2` but - // it's simpler this way and uses slightly less memory =) - oldlen = a->len; - arraylist_grow(a, 2); - a->len = oldlen; - JL_UNLOCK_NOGC(&finalizers_lock); - } - void **items = a->items; - items[oldlen] = v; - items[oldlen + 1] = f; - jl_atomic_store_release((_Atomic(size_t)*)&a->len, oldlen + 2); -} - -JL_DLLEXPORT void jl_gc_add_ptr_finalizer(jl_ptls_t ptls, jl_value_t *v, void *f) JL_NOTSAFEPOINT -{ - jl_gc_add_finalizer_(ptls, (void*)(((uintptr_t)v) | 1), f); -} - -// schedule f(v) to call at the next quiescent interval (aka after the next safepoint/region on all threads) -JL_DLLEXPORT void jl_gc_add_quiescent(jl_ptls_t ptls, void **v, void *f) JL_NOTSAFEPOINT -{ - assert(!gc_ptr_tag(v, 3)); - jl_gc_add_finalizer_(ptls, (void*)(((uintptr_t)v) | 3), f); -} - -JL_DLLEXPORT void jl_gc_add_finalizer_th(jl_ptls_t ptls, jl_value_t *v, jl_function_t *f) JL_NOTSAFEPOINT -{ - if (__unlikely(jl_typetagis(f, jl_voidpointer_type))) { - jl_gc_add_ptr_finalizer(ptls, v, jl_unbox_voidpointer(f)); - } - else { - jl_gc_add_finalizer_(ptls, v, f); - } -} - -JL_DLLEXPORT void jl_finalize_th(jl_task_t *ct, jl_value_t *o) -{ - JL_LOCK_NOGC(&finalizers_lock); - // Copy the finalizers into a temporary list so that code in the finalizer - // won't change the list as we loop through them. - // This list is also used as the GC frame when we are running the finalizers - arraylist_t copied_list; - arraylist_new(&copied_list, 0); - // No need to check the to_finalize list since the user is apparently - // still holding a reference to the object - int gc_n_threads; - jl_ptls_t* gc_all_tls_states; - gc_n_threads = jl_atomic_load_acquire(&jl_n_threads); - gc_all_tls_states = jl_atomic_load_relaxed(&jl_all_tls_states); - for (int i = 0; i < gc_n_threads; i++) { - jl_ptls_t ptls2 = gc_all_tls_states[i]; - if (ptls2 != NULL) - finalize_object(&ptls2->finalizers, o, &copied_list, jl_atomic_load_relaxed(&ct->tid) != i); - } - finalize_object(&finalizer_list_marked, o, &copied_list, 0); - if (copied_list.len > 0) { - // This releases the finalizers lock. - jl_gc_run_finalizers_in_list(ct, &copied_list); - } - else { - JL_UNLOCK_NOGC(&finalizers_lock); - } - arraylist_free(&copied_list); -} - // explicitly scheduled objects for the sweepfunc callback static void gc_sweep_foreign_objs_in_list(arraylist_t *objs) JL_NOTSAFEPOINT { @@ -705,13 +194,13 @@ static int64_t scanned_bytes; // young bytes scanned while marking static int64_t perm_scanned_bytes; // old bytes scanned while marking int prev_sweep_full = 1; int current_sweep_full = 0; +int next_sweep_full = 0; int under_pressure = 0; // Full collection heuristics static int64_t live_bytes = 0; static int64_t promoted_bytes = 0; static int64_t last_live_bytes = 0; // live_bytes at last collection -static int64_t t_start = 0; // Time GC starts; #ifdef __GLIBC__ // maxrss at last malloc_trim static int64_t last_trim_maxrss = 0; @@ -861,8 +350,7 @@ STATIC_INLINE void maybe_collect(jl_ptls_t ptls) // weak references -JL_DLLEXPORT jl_weakref_t *jl_gc_new_weakref_th(jl_ptls_t ptls, - jl_value_t *value) +JL_DLLEXPORT jl_weakref_t *jl_gc_new_weakref_th(jl_ptls_t ptls, jl_value_t *value) { jl_weakref_t *wr = (jl_weakref_t*)jl_gc_alloc(ptls, sizeof(void*), jl_weakref_type); @@ -3751,7 +3239,7 @@ static int _jl_gc_collect(jl_ptls_t ptls, jl_gc_collection_t collection) live_bytes += -gc_num.freed + gc_num.allocd; jl_timing_counter_dec(JL_TIMING_COUNTER_HeapSize, gc_num.freed); - gc_time_summary(sweep_full, t_start, gc_end_time, gc_num.freed, + gc_time_summary(sweep_full, gc_start_time, gc_end_time, gc_num.freed, live_bytes, gc_num.interval, pause, gc_num.time_to_safepoint, gc_num.mark_time, gc_num.sweep_time); @@ -3972,6 +3460,79 @@ void jl_start_gc_threads(void) } } +STATIC_INLINE int may_mark(void) JL_NOTSAFEPOINT +{ + return (jl_atomic_load(&gc_n_threads_marking) > 0); +} + +STATIC_INLINE int may_sweep(jl_ptls_t ptls) JL_NOTSAFEPOINT +{ + return (jl_atomic_load(&ptls->gc_tls.gc_sweeps_requested) > 0); +} + +// parallel gc thread function +void jl_parallel_gc_threadfun(void *arg) +{ + jl_threadarg_t *targ = (jl_threadarg_t*)arg; + + // initialize this thread (set tid and create heap) + jl_ptls_t ptls = jl_init_threadtls(targ->tid); + void *stack_lo, *stack_hi; + jl_init_stack_limits(0, &stack_lo, &stack_hi); + // warning: this changes `jl_current_task`, so be careful not to call that from this function + jl_task_t *ct = jl_init_root_task(ptls, stack_lo, stack_hi); + JL_GC_PROMISE_ROOTED(ct); + (void)jl_atomic_fetch_add_relaxed(&n_threads_running, -1); + // wait for all threads + jl_gc_state_set(ptls, JL_GC_PARALLEL_COLLECTOR_THREAD, JL_GC_STATE_UNSAFE); + uv_barrier_wait(targ->barrier); + + // free the thread argument here + free(targ); + + while (1) { + uv_mutex_lock(&gc_threads_lock); + while (!may_mark() && !may_sweep(ptls)) { + uv_cond_wait(&gc_threads_cond, &gc_threads_lock); + } + uv_mutex_unlock(&gc_threads_lock); + assert(jl_atomic_load_relaxed(&ptls->gc_state) == JL_GC_PARALLEL_COLLECTOR_THREAD); + gc_mark_loop_parallel(ptls, 0); + if (may_sweep(ptls)) { + assert(jl_atomic_load_relaxed(&ptls->gc_state) == JL_GC_PARALLEL_COLLECTOR_THREAD); + gc_sweep_pool_parallel(ptls); + jl_atomic_fetch_add(&ptls->gc_tls.gc_sweeps_requested, -1); + } + } +} + +// concurrent gc thread function +void jl_concurrent_gc_threadfun(void *arg) +{ + jl_threadarg_t *targ = (jl_threadarg_t*)arg; + + // initialize this thread (set tid and create heap) + jl_ptls_t ptls = jl_init_threadtls(targ->tid); + void *stack_lo, *stack_hi; + jl_init_stack_limits(0, &stack_lo, &stack_hi); + // warning: this changes `jl_current_task`, so be careful not to call that from this function + jl_task_t *ct = jl_init_root_task(ptls, stack_lo, stack_hi); + JL_GC_PROMISE_ROOTED(ct); + (void)jl_atomic_fetch_add_relaxed(&n_threads_running, -1); + // wait for all threads + jl_gc_state_set(ptls, JL_GC_CONCURRENT_COLLECTOR_THREAD, JL_GC_STATE_UNSAFE); + uv_barrier_wait(targ->barrier); + + // free the thread argument here + free(targ); + + while (1) { + assert(jl_atomic_load_relaxed(&ptls->gc_state) == JL_GC_CONCURRENT_COLLECTOR_THREAD); + uv_sem_wait(&gc_sweep_assists_needed); + gc_free_pages(); + } +} + // System-wide initializations void jl_gc_init(void) { @@ -3979,6 +3540,7 @@ void jl_gc_init(void) JL_MUTEX_INIT(&finalizers_lock, "finalizers_lock"); uv_mutex_init(&page_profile_lock); uv_mutex_init(&gc_perm_lock); + uv_mutex_init(&gc_pages_lock); uv_mutex_init(&gc_threads_lock); uv_cond_init(&gc_threads_cond); uv_sem_init(&gc_sweep_assists_needed, 0); @@ -3996,7 +3558,6 @@ void jl_gc_init(void) arraylist_new(&to_finalize, 0); jl_atomic_store_relaxed(&gc_heap_stats.heap_target, default_collect_interval); gc_num.interval = default_collect_interval; - last_long_collect_interval = default_collect_interval; gc_num.allocd = 0; gc_num.max_pause = 0; gc_num.max_memory = 0; @@ -4017,8 +3578,6 @@ void jl_gc_init(void) hint = min_heap_size_hint; jl_gc_set_max_memory(hint - mem_reserve); } - - t_start = jl_hrtime(); } JL_DLLEXPORT void jl_gc_set_max_memory(uint64_t max_mem) @@ -4034,12 +3593,6 @@ JL_DLLEXPORT uint64_t jl_gc_get_max_memory(void) return max_total_memory; } -// callback for passing OOM errors from gmp -JL_DLLEXPORT void jl_throw_out_of_memory_error(void) -{ - jl_throw(jl_memory_exception); -} - // allocation wrappers that track allocation and let collection run JL_DLLEXPORT void *jl_gc_counted_malloc(size_t sz) @@ -4244,7 +3797,7 @@ STATIC_INLINE void *gc_try_perm_alloc_pool(size_t sz, unsigned align, unsigned o } // **NOT** a safepoint -void *jl_gc_perm_alloc_nolock(size_t sz, int zero, unsigned align, unsigned offset) +void *jl_gc_perm_alloc_nolock(size_t sz, int zero, unsigned align, unsigned offset) JL_NOTSAFEPOINT { // The caller should have acquired `gc_perm_lock` assert(align < GC_PERM_POOL_LIMIT); @@ -4289,15 +3842,16 @@ void *jl_gc_perm_alloc(size_t sz, int zero, unsigned align, unsigned offset) return p; } -JL_DLLEXPORT void jl_gc_add_finalizer(jl_value_t *v, jl_function_t *f) -{ - jl_ptls_t ptls = jl_current_task->ptls; - jl_gc_add_finalizer_th(ptls, v, f); -} - -JL_DLLEXPORT void jl_finalize(jl_value_t *o) +jl_value_t *jl_gc_permobj(size_t sz, void *ty) JL_NOTSAFEPOINT { - jl_finalize_th(jl_current_task, o); + const size_t allocsz = sz + sizeof(jl_taggedvalue_t); + unsigned align = (sz == 0 ? sizeof(void*) : (allocsz <= sizeof(void*) * 2 ? + sizeof(void*) * 2 : 16)); + jl_taggedvalue_t *o = (jl_taggedvalue_t*)jl_gc_perm_alloc(allocsz, 0, align, + sizeof(void*) % align); + uintptr_t tag = (uintptr_t)ty; + o->header = tag | GC_OLD_MARKED; + return jl_valueof(o); } JL_DLLEXPORT jl_weakref_t *jl_gc_new_weakref(jl_value_t *value) diff --git a/src/gc.h b/src/gc-stock.h similarity index 92% rename from src/gc.h rename to src/gc-stock.h index e22ded0ec6740..7176ad8b504f4 100644 --- a/src/gc.h +++ b/src/gc-stock.h @@ -18,16 +18,8 @@ #include "julia.h" #include "julia_threads.h" #include "julia_internal.h" -#include "threading.h" -#ifndef _OS_WINDOWS_ -#include -#if defined(_OS_DARWIN_) && !defined(MAP_ANONYMOUS) -#define MAP_ANONYMOUS MAP_ANON -#endif -#endif #include "julia_assert.h" -#include "gc-heap-snapshot.h" -#include "gc-alloc-profiler.h" +#include "threading.h" #ifdef __cplusplus extern "C" { @@ -41,9 +33,6 @@ extern "C" { #define GC_PAGE_SZ (1 << GC_PAGE_LG2) #define GC_PAGE_OFFSET (JL_HEAP_ALIGNMENT - (sizeof(jl_taggedvalue_t) % JL_HEAP_ALIGNMENT)) -#define jl_malloc_tag ((void*)0xdeadaa01) -#define jl_singleton_tag ((void*)0xdeadaa02) - // Used by GC_DEBUG_ENV typedef struct { uint64_t num; @@ -62,34 +51,6 @@ typedef struct { jl_alloc_num_t print; } jl_gc_debug_env_t; -// This struct must be kept in sync with the Julia type of the same name in base/timing.jl -typedef struct { - int64_t allocd; - int64_t deferred_alloc; - int64_t freed; - uint64_t malloc; - uint64_t realloc; - uint64_t poolalloc; - uint64_t bigalloc; - uint64_t freecall; - uint64_t total_time; - uint64_t total_allocd; - size_t interval; - int pause; - int full_sweep; - uint64_t max_pause; - uint64_t max_memory; - uint64_t time_to_safepoint; - uint64_t max_time_to_safepoint; - uint64_t total_time_to_safepoint; - uint64_t sweep_time; - uint64_t mark_time; - uint64_t total_sweep_time; - uint64_t total_mark_time; - uint64_t last_full_sweep; - uint64_t last_incremental_sweep; -} jl_gc_num_t; - // Array chunks (work items representing suffixes of // large arrays of pointers left to be marked) @@ -440,14 +401,9 @@ STATIC_INLINE unsigned ffs_u32(uint32_t bitvec) } #endif -extern jl_gc_num_t gc_num; extern bigval_t *oldest_generation_of_bigvals; -extern arraylist_t finalizer_list_marked; -extern arraylist_t to_finalize; extern int64_t buffered_pages; extern int gc_first_tid; -extern int gc_n_threads; -extern jl_ptls_t* gc_all_tls_states; extern gc_heapstatus_t gc_heap_stats; STATIC_INLINE int gc_first_parallel_collector_thread_id(void) JL_NOTSAFEPOINT @@ -523,31 +479,6 @@ STATIC_INLINE jl_taggedvalue_t *page_pfl_end(jl_gc_pagemeta_t *p) JL_NOTSAFEPOIN return (jl_taggedvalue_t*)(p->data + p->fl_end_offset); } -STATIC_INLINE int gc_marked(uintptr_t bits) JL_NOTSAFEPOINT -{ - return (bits & GC_MARKED) != 0; -} - -STATIC_INLINE int gc_old(uintptr_t bits) JL_NOTSAFEPOINT -{ - return (bits & GC_OLD) != 0; -} - -STATIC_INLINE uintptr_t gc_set_bits(uintptr_t tag, int bits) JL_NOTSAFEPOINT -{ - return (tag & ~(uintptr_t)3) | bits; -} - -STATIC_INLINE uintptr_t gc_ptr_tag(void *v, uintptr_t mask) JL_NOTSAFEPOINT -{ - return ((uintptr_t)v) & mask; -} - -STATIC_INLINE void *gc_ptr_clear_tag(void *v, uintptr_t mask) JL_NOTSAFEPOINT -{ - return (void*)(((uintptr_t)v) & ~mask); -} - FORCE_INLINE void gc_big_object_unlink(const bigval_t *node) JL_NOTSAFEPOINT { assert(node != oldest_generation_of_bigvals); @@ -574,11 +505,13 @@ FORCE_INLINE void gc_big_object_link(bigval_t *sentinel_node, bigval_t *node) JL sentinel_node->next = node; } +extern uv_mutex_t gc_perm_lock; extern uv_mutex_t gc_threads_lock; extern uv_cond_t gc_threads_cond; extern uv_sem_t gc_sweep_assists_needed; extern _Atomic(int) gc_n_threads_marking; extern _Atomic(int) gc_n_threads_sweeping; +extern _Atomic(int) n_threads_running; extern uv_barrier_t thread_init_done; void gc_mark_queue_all_roots(jl_ptls_t ptls, jl_gc_markqueue_t *mq); void gc_mark_finlist_(jl_gc_markqueue_t *mq, jl_value_t *fl_parent, jl_value_t **fl_begin, jl_value_t **fl_end) JL_NOTSAFEPOINT; @@ -593,6 +526,7 @@ void jl_gc_debug_init(void); // GC pages +extern uv_mutex_t gc_pages_lock; void jl_gc_init_page(void) JL_NOTSAFEPOINT; NOINLINE jl_gc_pagemeta_t *jl_gc_alloc_page(void) JL_NOTSAFEPOINT; void jl_gc_free_page(jl_gc_pagemeta_t *p) JL_NOTSAFEPOINT; diff --git a/src/gf.c b/src/gf.c index 659261d434659..5ae7644c01363 100644 --- a/src/gf.c +++ b/src/gf.c @@ -3669,7 +3669,7 @@ static int sort_mlmatches(jl_array_t *t, size_t idx, arraylist_t *visited, array int msp2 = !msp && jl_method_morespecific(m2, m); if (!msp) { if (subt || !include_ambiguous || (lim != -1 && msp2)) { - if (subt2 || jl_subtype((jl_value_t*)ti, m2->sig)) { + if (subt2 || ((lim != -1 || (!include_ambiguous && !msp2)) && jl_subtype((jl_value_t*)ti, m2->sig))) { // this may be filtered out as fully intersected, if applicable later mayexclude = 1; } diff --git a/src/init.c b/src/init.c index 4362c33ccad0f..eff786b564e54 100644 --- a/src/init.c +++ b/src/init.c @@ -746,6 +746,9 @@ JL_DLLEXPORT void julia_init(JL_IMAGE_SEARCH rel) // Make sure we finalize the tls callback before starting any threads. (void)jl_get_pgcstack(); + // initialize symbol-table lock + uv_mutex_init(&symtab_lock); + // initialize backtraces jl_init_profile_lock(); #ifdef _OS_WINDOWS_ diff --git a/src/intrinsics.cpp b/src/intrinsics.cpp index ad89abf6ca1a2..4bfe3f184d24b 100644 --- a/src/intrinsics.cpp +++ b/src/intrinsics.cpp @@ -405,7 +405,7 @@ static Value *emit_unboxed_coercion(jl_codectx_t &ctx, Type *to, Value *unboxed) } else if (!ty->isIntOrPtrTy() && !ty->isFloatingPointTy()) { assert(DL.getTypeSizeInBits(ty) == DL.getTypeSizeInBits(to)); - AllocaInst *cast = ctx.builder.CreateAlloca(ty); + AllocaInst *cast = emit_static_alloca(ctx, ty); setName(ctx.emission_context, cast, "coercion"); ctx.builder.CreateStore(unboxed, cast); unboxed = ctx.builder.CreateLoad(to, cast); @@ -498,7 +498,7 @@ static Value *emit_unbox(jl_codectx_t &ctx, Type *to, const jl_cgval_t &x, jl_va } // emit code to store a raw value into a destination -static void emit_unbox_store(jl_codectx_t &ctx, const jl_cgval_t &x, Value *dest, MDNode *tbaa_dest, unsigned alignment, bool isVolatile) +static void emit_unbox_store(jl_codectx_t &ctx, const jl_cgval_t &x, Value *dest, MDNode *tbaa_dest, Align alignment, bool isVolatile) { if (x.isghost) { // this can happen when a branch yielding a different type ends @@ -510,7 +510,7 @@ static void emit_unbox_store(jl_codectx_t &ctx, const jl_cgval_t &x, Value *dest if (!x.ispointer()) { // already unboxed, but sometimes need conversion (e.g. f32 -> i32) assert(x.V); Value *unboxed = zext_struct(ctx, x.V); - StoreInst *store = ctx.builder.CreateAlignedStore(unboxed, dest, Align(alignment)); + StoreInst *store = ctx.builder.CreateAlignedStore(unboxed, dest, alignment); store->setVolatile(isVolatile); jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, tbaa_dest); ai.decorateInst(store); @@ -518,7 +518,7 @@ static void emit_unbox_store(jl_codectx_t &ctx, const jl_cgval_t &x, Value *dest } Value *src = data_pointer(ctx, x); - emit_memcpy(ctx, dest, jl_aliasinfo_t::fromTBAA(ctx, tbaa_dest), src, jl_aliasinfo_t::fromTBAA(ctx, x.tbaa), jl_datatype_size(x.typ), alignment, julia_alignment(x.typ), isVolatile); + emit_memcpy(ctx, dest, jl_aliasinfo_t::fromTBAA(ctx, tbaa_dest), src, jl_aliasinfo_t::fromTBAA(ctx, x.tbaa), jl_datatype_size(x.typ), Align(alignment), Align(julia_alignment(x.typ)), isVolatile); } static jl_datatype_t *staticeval_bitstype(const jl_cgval_t &targ) @@ -770,7 +770,7 @@ static jl_cgval_t emit_pointerref(jl_codectx_t &ctx, ArrayRef argv) thePtr = ctx.builder.CreateInBoundsGEP(getInt8Ty(ctx.builder.getContext()), thePtr, im1); setName(ctx.emission_context, thePtr, "pointerref_src"); MDNode *tbaa = best_tbaa(ctx.tbaa(), ety); - emit_memcpy(ctx, strct, jl_aliasinfo_t::fromTBAA(ctx, tbaa), thePtr, jl_aliasinfo_t::fromTBAA(ctx, nullptr), size, sizeof(jl_value_t*), align_nb); + emit_memcpy(ctx, strct, jl_aliasinfo_t::fromTBAA(ctx, tbaa), thePtr, jl_aliasinfo_t::fromTBAA(ctx, nullptr), size, Align(sizeof(jl_value_t*)), Align(align_nb)); return mark_julia_type(ctx, strct, true, ety); } else { @@ -799,7 +799,7 @@ static jl_cgval_t emit_runtime_pointerset(jl_codectx_t &ctx, ArrayRef argv) { const jl_cgval_t &e = argv[0]; - const jl_cgval_t &x = argv[1]; + jl_cgval_t x = argv[1]; const jl_cgval_t &i = argv[2]; const jl_cgval_t &align = argv[3]; @@ -822,6 +822,9 @@ static jl_cgval_t emit_pointerset(jl_codectx_t &ctx, ArrayRef argv) return jl_cgval_t(); } emit_typecheck(ctx, x, ety, "pointerset"); + x = update_julia_type(ctx, x, ety); + if (x.typ == jl_bottom_type) + return jl_cgval_t(); Value *idx = emit_unbox(ctx, ctx.types().T_size, i, (jl_value_t*)jl_long_type); Value *im1 = ctx.builder.CreateSub(idx, ConstantInt::get(ctx.types().T_size, 1)); @@ -847,7 +850,7 @@ static jl_cgval_t emit_pointerset(jl_codectx_t &ctx, ArrayRef argv) setName(ctx.emission_context, im1, "pointerset_offset"); auto gep = ctx.builder.CreateInBoundsGEP(getInt8Ty(ctx.builder.getContext()), thePtr, im1); setName(ctx.emission_context, gep, "pointerset_ptr"); - emit_memcpy(ctx, gep, jl_aliasinfo_t::fromTBAA(ctx, nullptr), x, size, align_nb, julia_alignment(ety)); + emit_memcpy(ctx, gep, jl_aliasinfo_t::fromTBAA(ctx, nullptr), x, size, Align(align_nb), Align(julia_alignment(ety))); } else { bool isboxed; @@ -992,7 +995,7 @@ static jl_cgval_t emit_atomic_pointerop(jl_codectx_t &ctx, intrinsic f, ArrayRef bool ismodifyfield = f == atomic_pointermodify; const jl_cgval_t undefval; const jl_cgval_t &e = argv[0]; - const jl_cgval_t &x = isreplacefield || ismodifyfield ? argv[2] : argv[1]; + jl_cgval_t x = isreplacefield || ismodifyfield ? argv[2] : argv[1]; const jl_cgval_t &y = isreplacefield || ismodifyfield ? argv[1] : undefval; const jl_cgval_t &ord = isreplacefield || ismodifyfield ? argv[3] : argv[2]; const jl_cgval_t &failord = isreplacefield ? argv[4] : undefval; @@ -1034,8 +1037,12 @@ static jl_cgval_t emit_atomic_pointerop(jl_codectx_t &ctx, intrinsic f, ArrayRef emit_error(ctx, msg); return jl_cgval_t(); } - if (!ismodifyfield) + if (!ismodifyfield) { emit_typecheck(ctx, x, ety, std::string(jl_intrinsic_name((int)f))); + x = update_julia_type(ctx, x, ety); + if (x.typ == jl_bottom_type) + return jl_cgval_t(); + } size_t nb = jl_datatype_size(ety); if ((nb & (nb - 1)) != 0 || nb > MAX_POINTERATOMIC_SIZE) { diff --git a/src/jitlayers.cpp b/src/jitlayers.cpp index 487e6a0462500..442103c91be0f 100644 --- a/src/jitlayers.cpp +++ b/src/jitlayers.cpp @@ -3,7 +3,7 @@ #include "llvm-version.h" #include "platform.h" #include -#include +#include #include "llvm/IR/Mangler.h" #include @@ -42,7 +42,11 @@ using namespace llvm; #include "julia_assert.h" #include "processor.h" +#if JL_LLVM_VERSION >= 180000 +# include +#else # include +#endif # include # include # include @@ -564,6 +568,19 @@ jl_value_t *jl_dump_method_asm_impl(jl_method_instance_t *mi, size_t world, return jl_an_empty_string; } +#if JL_LLVM_VERSION >= 180000 +CodeGenOptLevel CodeGenOptLevelFor(int optlevel) +{ +#ifdef DISABLE_OPT + return CodeGenOptLevel::None; +#else + return optlevel == 0 ? CodeGenOptLevel::None : + optlevel == 1 ? CodeGenOptLevel::Less : + optlevel == 2 ? CodeGenOptLevel::Default : + CodeGenOptLevel::Aggressive; +#endif +} +#else CodeGenOpt::Level CodeGenOptLevelFor(int optlevel) { #ifdef DISABLE_OPT @@ -575,6 +592,7 @@ CodeGenOpt::Level CodeGenOptLevelFor(int optlevel) CodeGenOpt::Aggressive; #endif } +#endif static auto countBasicBlocks(const Function &F) JL_NOTSAFEPOINT { @@ -589,7 +607,7 @@ static Expected validateExternRelocations(orc::ThreadSafe auto F = dyn_cast(&GO); if (!F) return false; - return F->isIntrinsic() || F->getName().startswith("julia."); + return F->isIntrinsic() || F->getName().starts_with("julia."); }; // validate the relocations for M (only for RuntimeDyld, JITLink performs its own symbol validation) auto Err = TSM.withModuleDo([isIntrinsicFunction](Module &M) JL_NOTSAFEPOINT { @@ -1157,7 +1175,7 @@ namespace { { if (*jl_ExecutionEngine->get_dump_llvm_opt_stream()) { for (auto &F : M.functions()) { - if (F.isDeclaration() || F.getName().startswith("jfptr_")) { + if (F.isDeclaration() || F.getName().starts_with("jfptr_")) { continue; } // Each function is printed as a YAML object with several attributes @@ -1210,7 +1228,7 @@ namespace { // Print LLVM function statistics _after_ optimization ios_printf(stream, " after: \n"); for (auto &F : M.functions()) { - if (F.isDeclaration() || F.getName().startswith("jfptr_")) { + if (F.isDeclaration() || F.getName().starts_with("jfptr_")) { continue; } Stat(F).dump(stream); @@ -1397,7 +1415,7 @@ struct JuliaOJIT::DLSymOptimizer { void operator()(Module &M) { for (auto &GV : M.globals()) { auto Name = GV.getName(); - if (Name.startswith("jlplt") && Name.endswith("got")) { + if (Name.starts_with("jlplt") && Name.ends_with("got")) { auto fname = GV.getAttribute("julia.fname").getValueAsString().str(); void *addr; if (GV.hasAttribute("julia.libname")) { @@ -1651,7 +1669,7 @@ JuliaOJIT::JuliaOJIT() DL.getGlobalPrefix(), [&](const orc::SymbolStringPtr &S) { const char *const atomic_prefix = "__atomic_"; - return (*S).startswith(atomic_prefix); + return (*S).starts_with(atomic_prefix); }))); } } @@ -2208,8 +2226,15 @@ static void jl_decorate_module(Module &M) { // Add special values used by debuginfo to build the UnwindData table registration for Win64 // This used to be GV, but with https://reviews.llvm.org/D100944 we no longer can emit GV into `.text` // TODO: The data is set in debuginfo.cpp but it should be okay to actually emit it here. - M.appendModuleInlineAsm("\ - .section .text \n\ + std::string inline_asm = "\ + .section "; + inline_asm += +#if JL_LLVM_VERSION >= 180000 + ".ltext,\"ax\",@progbits"; +#else + ".text"; +#endif + inline_asm += "\n\ .type __UnwindData,@object \n\ .p2align 2, 0x90 \n\ __UnwindData: \n\ @@ -2220,7 +2245,9 @@ static void jl_decorate_module(Module &M) { .p2align 2, 0x90 \n\ __catchjmp: \n\ .zero 12 \n\ - .size __catchjmp, 12"); + .size __catchjmp, 12"; + + M.appendModuleInlineAsm(inline_asm); } } diff --git a/src/jitlayers.h b/src/jitlayers.h index 101f5714abd11..107782e354d4a 100644 --- a/src/jitlayers.h +++ b/src/jitlayers.h @@ -26,6 +26,7 @@ #include "julia_internal.h" #include "platform.h" #include "llvm-codegen-shared.h" +#include "llvm-version.h" #include #include @@ -645,4 +646,8 @@ void optimizeDLSyms(Module &M); // NewPM #include "passes.h" +#if JL_LLVM_VERSION >= 180000 +CodeGenOptLevel CodeGenOptLevelFor(int optlevel) JL_NOTSAFEPOINT; +#else CodeGenOpt::Level CodeGenOptLevelFor(int optlevel) JL_NOTSAFEPOINT; +#endif diff --git a/src/jl_exported_funcs.inc b/src/jl_exported_funcs.inc index 246b666f942c1..1976dbe709733 100644 --- a/src/jl_exported_funcs.inc +++ b/src/jl_exported_funcs.inc @@ -542,7 +542,6 @@ YY(jl_type_to_llvm) \ YY(jl_getUnwindInfo) \ YY(jl_get_libllvm) \ - YY(jl_build_newpm_pipeline) \ YY(jl_register_passbuilder_callbacks) \ YY(LLVMExtraMPMAddCPUFeaturesPass) \ YY(LLVMExtraMPMAddRemoveNIPass) \ diff --git a/src/jltypes.c b/src/jltypes.c index 10b8bc937939e..5dc50ff0ca4e6 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -1961,7 +1961,7 @@ static jl_value_t *jl_tupletype_fill(size_t n, jl_value_t *t, int check, int not t = normalize_unionalls(t); p = t; jl_value_t *tw = extract_wrapper(t); - if (tw && t != tw && jl_types_equal(t, tw)) + if (tw && t != tw && !jl_has_free_typevars(t) && jl_types_equal(t, tw)) t = tw; p = t; check = 0; // remember that checks are already done now @@ -2045,7 +2045,7 @@ static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value // normalize types equal to wrappers (prepare for Typeofwrapper) jl_value_t *tw = extract_wrapper(pi); if (tw && tw != pi && (tn != jl_type_typename || jl_typeof(pi) == jl_typeof(tw)) && - jl_types_equal(pi, tw)) { + !jl_has_free_typevars(pi) && jl_types_equal(pi, tw)) { iparams[i] = tw; if (p) jl_gc_wb(p, tw); } @@ -2717,7 +2717,7 @@ jl_vararg_t *jl_wrap_vararg(jl_value_t *t, jl_value_t *n, int check, int nothrow if (valid) { t = normalize_unionalls(t); jl_value_t *tw = extract_wrapper(t); - if (tw && t != tw && jl_types_equal(t, tw)) + if (tw && t != tw && !jl_has_free_typevars(t) && jl_types_equal(t, tw)) t = tw; } } @@ -2895,25 +2895,26 @@ void jl_init_types(void) JL_GC_DISABLED jl_typename_type->name->mt = jl_nonfunction_mt; jl_typename_type->super = jl_any_type; jl_typename_type->parameters = jl_emptysvec; - jl_typename_type->name->n_uninitialized = 15 - 2; - jl_typename_type->name->names = jl_perm_symsvec(15, "name", "module", + jl_typename_type->name->n_uninitialized = 16 - 2; + jl_typename_type->name->names = jl_perm_symsvec(16, "name", "module", "names", "atomicfields", "constfields", "wrapper", "Typeofwrapper", "cache", "linearcache", "mt", "partial", "hash", "n_uninitialized", "flags", // "abstract", "mutable", "mayinlinealloc", - "max_methods"); + "max_methods", "constprop_heuristic"); const static uint32_t typename_constfields[1] = { 0x00003a27 }; // (1<<0)|(1<<1)|(1<<2)|(1<<5)|(1<<9)|(1<<11)|(1<<12)|(1<<13) ; TODO: put back (1<<3)|(1<<4) in this list const static uint32_t typename_atomicfields[1] = { 0x00000180 }; // (1<<7)|(1<<8) jl_typename_type->name->constfields = typename_constfields; jl_typename_type->name->atomicfields = typename_atomicfields; jl_precompute_memoized_dt(jl_typename_type, 1); - jl_typename_type->types = jl_svec(15, jl_symbol_type, jl_any_type /*jl_module_type*/, + jl_typename_type->types = jl_svec(16, jl_symbol_type, jl_any_type /*jl_module_type*/, jl_simplevector_type, jl_any_type/*jl_voidpointer_type*/, jl_any_type/*jl_voidpointer_type*/, jl_type_type, jl_type_type, jl_simplevector_type, jl_simplevector_type, jl_methtable_type, jl_any_type, jl_any_type /*jl_long_type*/, jl_any_type /*jl_int32_type*/, jl_any_type /*jl_uint8_type*/, + jl_any_type /*jl_uint8_type*/, jl_any_type /*jl_uint8_type*/); jl_methtable_type->name = jl_new_typename_in(jl_symbol("MethodTable"), core, 0, 1); @@ -3690,6 +3691,7 @@ void jl_init_types(void) JL_GC_DISABLED jl_svecset(jl_typename_type->types, 12, jl_int32_type); jl_svecset(jl_typename_type->types, 13, jl_uint8_type); jl_svecset(jl_typename_type->types, 14, jl_uint8_type); + jl_svecset(jl_typename_type->types, 15, jl_uint8_type); jl_svecset(jl_methtable_type->types, 4, jl_long_type); jl_svecset(jl_methtable_type->types, 5, jl_module_type); jl_svecset(jl_methtable_type->types, 6, jl_array_any_type); diff --git a/src/julia.h b/src/julia.h index 4574c47518d81..e211f31c6512c 100644 --- a/src/julia.h +++ b/src/julia.h @@ -27,22 +27,10 @@ #include #ifndef _OS_WINDOWS_ -# define jl_jmp_buf sigjmp_buf -# if defined(_CPU_ARM_) || defined(_CPU_PPC_) || defined(_CPU_WASM_) -# define MAX_ALIGN 8 -# elif defined(_CPU_AARCH64_) -// int128 is 16 bytes aligned on aarch64 -# define MAX_ALIGN 16 -# elif defined(_P64) -// Generically we assume MAX_ALIGN is sizeof(void*) -# define MAX_ALIGN 8 -# else -# define MAX_ALIGN 4 -# endif + #define jl_jmp_buf sigjmp_buf #else -# include "win32_ucontext.h" -# define jl_jmp_buf jmp_buf -# define MAX_ALIGN 8 + #include "win32_ucontext.h" + #define jl_jmp_buf jmp_buf #endif // Define the largest size (bytes) of a properly aligned object that the @@ -82,6 +70,7 @@ typedef struct _jl_tls_states_t *jl_ptls_t; #ifdef JL_LIBRARY_EXPORTS #include "uv.h" #endif +#include "gc-interface.h" #include "julia_atomics.h" #include "julia_threads.h" #include "julia_assert.h" @@ -282,11 +271,12 @@ typedef union __jl_purity_overrides_t { uint16_t ipo_noub : 1; uint16_t ipo_noub_if_noinbounds : 1; uint16_t ipo_consistent_overlay : 1; + uint16_t ipo_nortcall : 1; } overrides; uint16_t bits; } _jl_purity_overrides_t; -#define NUM_EFFECTS_OVERRIDES 10 +#define NUM_EFFECTS_OVERRIDES 11 #define NUM_IR_FLAGS 13 // This type describes a single function body @@ -299,16 +289,15 @@ typedef struct _jl_code_info_t { // 1 << 0 = inbounds region // 1 << 1 = callsite inline region // 1 << 2 = callsite noinline region - // 1 << 3 = throw block - // 1 << 4 = refined statement - // 1 << 5 = :consistent - // 1 << 6 = :effect_free - // 1 << 7 = :nothrow - // 1 << 8 = :terminates - // 1 << 9 = :noub - // 1 << 10 = :effect_free_if_inaccessiblememonly - // 1 << 11 = :inaccessiblemem_or_argmemonly - // 1 << 12-19 = callsite effects overrides + // 1 << 3 = refined statement + // 1 << 4 = :consistent + // 1 << 5 = :effect_free + // 1 << 6 = :nothrow + // 1 << 7 = :terminates + // 1 << 8 = :noub + // 1 << 9 = :effect_free_if_inaccessiblememonly + // 1 << 10 = :inaccessiblemem_or_argmemonly + // 1 << 11-19 = callsite effects overrides // miscellaneous data: jl_array_t *slotnames; // names of local variables jl_array_t *slotflags; // local var bit flags @@ -531,6 +520,7 @@ typedef struct { uint8_t mayinlinealloc:1; uint8_t _reserved:5; uint8_t max_methods; // override for inference's max_methods setting (0 = no additional limit or relaxation) + uint8_t constprop_heustic; // override for inference's constprop heuristic } jl_typename_t; typedef struct { @@ -1046,35 +1036,14 @@ extern void JL_GC_POP() JL_NOTSAFEPOINT; #endif -JL_DLLEXPORT int jl_gc_enable(int on); -JL_DLLEXPORT int jl_gc_is_enabled(void); - -typedef enum { - JL_GC_AUTO = 0, // use heuristics to determine the collection type - JL_GC_FULL = 1, // force a full collection - JL_GC_INCREMENTAL = 2, // force an incremental collection -} jl_gc_collection_t; - -JL_DLLEXPORT void jl_gc_collect(jl_gc_collection_t); - JL_DLLEXPORT void jl_gc_add_finalizer(jl_value_t *v, jl_function_t *f) JL_NOTSAFEPOINT; JL_DLLEXPORT void jl_gc_add_ptr_finalizer(jl_ptls_t ptls, jl_value_t *v, void *f) JL_NOTSAFEPOINT; JL_DLLEXPORT void jl_gc_add_quiescent(jl_ptls_t ptls, void **v, void *f) JL_NOTSAFEPOINT; JL_DLLEXPORT void jl_finalize(jl_value_t *o); -JL_DLLEXPORT jl_weakref_t *jl_gc_new_weakref(jl_value_t *value); -JL_DLLEXPORT jl_value_t *jl_gc_allocobj(size_t sz); JL_DLLEXPORT void *jl_malloc_stack(size_t *bufsz, struct _jl_task_t *owner) JL_NOTSAFEPOINT; JL_DLLEXPORT void jl_free_stack(void *stkbuf, size_t bufsz); -JL_DLLEXPORT void jl_gc_use(jl_value_t *a); -// Set GC memory trigger in bytes for greedy memory collecting -JL_DLLEXPORT void jl_gc_set_max_memory(uint64_t max_mem); -JL_DLLEXPORT uint64_t jl_gc_get_max_memory(void); - -JL_DLLEXPORT void jl_clear_malloc_data(void); // GC write barriers -JL_DLLEXPORT void jl_gc_queue_root(const jl_value_t *root) JL_NOTSAFEPOINT; -JL_DLLEXPORT void jl_gc_queue_multiroot(const jl_value_t *root, const void *stored, jl_datatype_t *dt) JL_NOTSAFEPOINT; STATIC_INLINE void jl_gc_wb(const void *parent, const void *ptr) JL_NOTSAFEPOINT { @@ -1106,7 +1075,6 @@ STATIC_INLINE void jl_gc_multi_wb(const void *parent, const jl_value_t *ptr) JL_ jl_gc_queue_multiroot((jl_value_t*)parent, ptr, dt); } -JL_DLLEXPORT void *jl_gc_managed_malloc(size_t sz); JL_DLLEXPORT void jl_gc_safepoint(void); JL_DLLEXPORT int jl_safepoint_suspend_thread(int tid, int waitstate); JL_DLLEXPORT void jl_safepoint_suspend_all_threads(struct _jl_task_t *ct); diff --git a/src/julia_internal.h b/src/julia_internal.h index 22c5cdb9a445f..d4d1a3239785c 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -17,6 +17,8 @@ #include #include #include +#include + #if !defined(_WIN32) #include #else @@ -98,6 +100,26 @@ JL_DLLIMPORT void __tsan_destroy_fiber(void *fiber); JL_DLLIMPORT void __tsan_switch_to_fiber(void *fiber, unsigned flags); #endif +#ifndef _OS_WINDOWS_ + #if defined(_CPU_ARM_) || defined(_CPU_PPC_) || defined(_CPU_WASM_) + #define MAX_ALIGN 8 + #elif defined(_CPU_AARCH64_) || (JL_LLVM_VERSION >= 180000 && (defined(_CPU_X86_64_) || defined(_CPU_X86_))) + // int128 is 16 bytes aligned on aarch64 and on x86 with LLVM >= 18 + #define MAX_ALIGN 16 + #elif defined(_P64) + // Generically we assume MAX_ALIGN is sizeof(void*) + #define MAX_ALIGN 8 + #else + #define MAX_ALIGN 4 + #endif +#else + #if JL_LLVM_VERSION >= 180000 + #define MAX_ALIGN 16 + #else + #define MAX_ALIGN 8 + #endif +#endif + #ifndef alignof # ifndef __cplusplus # ifdef __GNUC__ @@ -311,7 +333,7 @@ static inline void memassign_safe(int hasptr, char *dst, const jl_value_t *src, memcpy(dst, jl_assume_aligned(src, sizeof(void*)), nb); } -// -- gc.c -- // +// -- GC -- // #define GC_CLEAN 0 // freshly allocated #define GC_MARKED 1 // reachable and young @@ -350,11 +372,6 @@ jl_value_t *jl_gc_small_alloc_noinline(jl_ptls_t ptls, int offset, int osize); jl_value_t *jl_gc_big_alloc_noinline(jl_ptls_t ptls, size_t allocsz); JL_DLLEXPORT int jl_gc_classify_pools(size_t sz, int *osize) JL_NOTSAFEPOINT; -extern uv_mutex_t gc_perm_lock; -void *jl_gc_perm_alloc_nolock(size_t sz, int zero, - unsigned align, unsigned offset) JL_NOTSAFEPOINT; -JL_DLLEXPORT void *jl_gc_perm_alloc(size_t sz, int zero, - unsigned align, unsigned offset) JL_NOTSAFEPOINT; void gc_sweep_sysimg(void); @@ -547,17 +564,6 @@ STATIC_INLINE jl_gc_tracked_buffer_t *jl_gc_alloc_buf(jl_ptls_t ptls, size_t sz) return jl_gc_alloc(ptls, sz, (void*)jl_buff_tag); } -STATIC_INLINE jl_value_t *jl_gc_permobj(size_t sz, void *ty) JL_NOTSAFEPOINT -{ - const size_t allocsz = sz + sizeof(jl_taggedvalue_t); - unsigned align = (sz == 0 ? sizeof(void*) : (allocsz <= sizeof(void*) * 2 ? - sizeof(void*) * 2 : 16)); - jl_taggedvalue_t *o = (jl_taggedvalue_t*)jl_gc_perm_alloc(allocsz, 0, align, - sizeof(void*) % align); - uintptr_t tag = (uintptr_t)ty; - o->header = tag | GC_OLD_MARKED; - return jl_valueof(o); -} jl_value_t *jl_permbox8(jl_datatype_t *t, uintptr_t tag, uint8_t x); jl_value_t *jl_permbox32(jl_datatype_t *t, uintptr_t tag, uint32_t x); jl_svec_t *jl_perm_symsvec(size_t n, ...); @@ -593,14 +599,6 @@ jl_svec_t *jl_perm_symsvec(size_t n, ...); #endif #endif -JL_DLLEXPORT void *jl_gc_counted_malloc(size_t sz); - -JL_DLLEXPORT void JL_NORETURN jl_throw_out_of_memory_error(void); - - -JL_DLLEXPORT int64_t jl_gc_diff_total_bytes(void) JL_NOTSAFEPOINT; -JL_DLLEXPORT int64_t jl_gc_sync_total_bytes(int64_t offset) JL_NOTSAFEPOINT; -void jl_gc_track_malloced_array(jl_ptls_t ptls, jl_array_t *a) JL_NOTSAFEPOINT; void jl_gc_track_malloced_genericmemory(jl_ptls_t ptls, jl_genericmemory_t *m, int isaligned) JL_NOTSAFEPOINT; size_t jl_genericmemory_nbytes(jl_genericmemory_t *a) JL_NOTSAFEPOINT; void jl_gc_count_allocd(size_t sz) JL_NOTSAFEPOINT; @@ -948,9 +946,7 @@ void jl_init_tasks(void) JL_GC_DISABLED; void jl_init_stack_limits(int ismaster, void **stack_hi, void **stack_lo) JL_NOTSAFEPOINT; jl_task_t *jl_init_root_task(jl_ptls_t ptls, void *stack_lo, void *stack_hi); void jl_init_serializer(void); -void jl_gc_init(void); void jl_init_uv(void); -void jl_init_thread_heap(jl_ptls_t ptls) JL_NOTSAFEPOINT; void jl_init_int32_int64_cache(void); JL_DLLEXPORT void jl_init_options(void); @@ -960,7 +956,6 @@ extern JL_DLLEXPORT ssize_t jl_tls_offset; extern JL_DLLEXPORT const int jl_tls_elf_support; void jl_init_threading(void); void jl_start_threads(void); -void jl_start_gc_threads(void); // Whether the GC is running extern uv_mutex_t safepoint_lock; @@ -1304,6 +1299,9 @@ void jl_push_excstack(jl_task_t *ct, jl_excstack_t **stack JL_REQUIRE_ROOTED_SLO jl_value_t *exception JL_ROOTED_ARGUMENT, jl_bt_element_t *bt_data, size_t bt_size); +// System util to get maximum RSS +JL_DLLEXPORT size_t jl_maxrss(void); + //-------------------------------------------------- // congruential random number generator // for a small amount of thread-local randomness @@ -1699,6 +1697,7 @@ void jl_write_malloc_log(void); # define jl_unreachable() ((void)jl_assume(0)) #endif +extern uv_mutex_t symtab_lock; jl_sym_t *_jl_symbol(const char *str, size_t len) JL_NOTSAFEPOINT; // Tools for locally disabling spurious compiler warnings diff --git a/src/llvm-alloc-helpers.cpp b/src/llvm-alloc-helpers.cpp index 953ecc1830142..9d2fba832839c 100644 --- a/src/llvm-alloc-helpers.cpp +++ b/src/llvm-alloc-helpers.cpp @@ -88,6 +88,8 @@ bool AllocUseInfo::addMemOp(Instruction *inst, unsigned opno, uint32_t offset, memop.isaggr = isa(elty) || isa(elty) || isa(elty); memop.isobjref = hasObjref(elty); auto &field = getField(offset, size, elty); + field.second.hasunboxed |= !hasObjref(elty) || (hasObjref(elty) && !isa(elty)); + if (field.second.hasobjref != memop.isobjref) field.second.multiloc = true; // can't split this field, since it contains a mix of references and bits if (!isstore) @@ -198,6 +200,7 @@ void jl_alloc::runEscapeAnalysis(llvm::CallInst *I, EscapeAnalysisRequiredArgs r auto elty = inst->getType(); required.use_info.has_unknown_objref |= hasObjref(elty); required.use_info.has_unknown_objrefaggr |= hasObjref(elty) && !isa(elty); + required.use_info.has_unknown_unboxed |= !hasObjref(elty) || (hasObjref(elty) && !isa(elty)); required.use_info.hasunknownmem = true; } else if (!required.use_info.addMemOp(inst, 0, cur.offset, inst->getType(), @@ -289,6 +292,7 @@ void jl_alloc::runEscapeAnalysis(llvm::CallInst *I, EscapeAnalysisRequiredArgs r auto elty = storev->getType(); required.use_info.has_unknown_objref |= hasObjref(elty); required.use_info.has_unknown_objrefaggr |= hasObjref(elty) && !isa(elty); + required.use_info.has_unknown_unboxed |= !hasObjref(elty) || (hasObjref(elty) && !isa(elty)); required.use_info.hasunknownmem = true; } else if (!required.use_info.addMemOp(inst, use->getOperandNo(), cur.offset, storev->getType(), @@ -310,10 +314,14 @@ void jl_alloc::runEscapeAnalysis(llvm::CallInst *I, EscapeAnalysisRequiredArgs r } required.use_info.hasload = true; auto storev = isa(inst) ? cast(inst)->getNewValOperand() : cast(inst)->getValOperand(); + Type *elty = storev->getType(); if (cur.offset == UINT32_MAX || !required.use_info.addMemOp(inst, use->getOperandNo(), - cur.offset, storev->getType(), + cur.offset, elty, true, required.DL)) { LLVM_DEBUG(dbgs() << "Atomic inst has unknown offset\n"); + required.use_info.has_unknown_objref |= hasObjref(elty); + required.use_info.has_unknown_objrefaggr |= hasObjref(elty) && !isa(elty); + required.use_info.has_unknown_unboxed |= !hasObjref(elty) || (hasObjref(elty) && !isa(elty)); required.use_info.hasunknownmem = true; } required.use_info.refload = true; diff --git a/src/llvm-alloc-helpers.h b/src/llvm-alloc-helpers.h index 49c3b15332a56..20e9132d10b4c 100644 --- a/src/llvm-alloc-helpers.h +++ b/src/llvm-alloc-helpers.h @@ -46,6 +46,8 @@ namespace jl_alloc { bool hasaggr:1; bool multiloc:1; bool hasload:1; + // The alloc has a unboxed object at this offset. + bool hasunboxed:1; llvm::Type *elty; llvm::SmallVector accesses; Field(uint32_t size, llvm::Type *elty) @@ -54,6 +56,7 @@ namespace jl_alloc { hasaggr(false), multiloc(false), hasload(false), + hasunboxed(false), elty(elty) { } @@ -95,6 +98,9 @@ namespace jl_alloc { // The alloc has an aggregate Julia object reference not in an explicit field. bool has_unknown_objrefaggr:1; + // The alloc has an unboxed object at an unknown offset. + bool has_unknown_unboxed:1; + void reset() { escaped = false; @@ -110,6 +116,7 @@ namespace jl_alloc { allockind = llvm::AllocFnKind::Unknown; has_unknown_objref = false; has_unknown_objrefaggr = false; + has_unknown_unboxed = false; uses.clear(); preserves.clear(); memops.clear(); diff --git a/src/llvm-alloc-opt.cpp b/src/llvm-alloc-opt.cpp index e0cde7206b6b9..5984ad55d221c 100644 --- a/src/llvm-alloc-opt.cpp +++ b/src/llvm-alloc-opt.cpp @@ -252,10 +252,12 @@ void Optimizer::optimizeAll() removeAlloc(orig); continue; } + bool has_unboxed = use_info.has_unknown_unboxed; bool has_ref = use_info.has_unknown_objref; bool has_refaggr = use_info.has_unknown_objrefaggr; for (auto memop: use_info.memops) { auto &field = memop.second; + has_unboxed |= field.hasunboxed; if (field.hasobjref) { has_ref = true; // This can be relaxed a little based on hasload @@ -284,6 +286,19 @@ void Optimizer::optimizeAll() splitOnStack(orig); continue; } + // The move to stack code below, if has_ref is set, changes the allocation to an array of jlvalue_t's. This is fine + // if all objects are jlvalue_t's. However, if part of the allocation is an unboxed value (e.g. it is a { float, jlvaluet }), + // then moveToStack will create a [2 x jlvaluet] bitcast to { float, jlvaluet }. + // This later causes the GC rooting pass, to miss-characterize the float as a pointer to a GC value + if (has_unboxed && has_ref) { + REMARK([&]() { + return OptimizationRemarkMissed(DEBUG_TYPE, "Escaped", orig) + << "GC allocation could not be split since it contains both boxed and unboxed values, unable to move to stack " << ore::NV("GC Allocation", orig); + }); + if (use_info.hastypeof) + optimizeTag(orig); + continue; + } REMARK([&](){ return OptimizationRemark(DEBUG_TYPE, "Stack Move Allocation", orig) << "GC allocation moved to stack " << ore::NV("GC Allocation", orig); diff --git a/src/llvm-cpufeatures.cpp b/src/llvm-cpufeatures.cpp index 2539c5cd2e37c..05d62adc57926 100644 --- a/src/llvm-cpufeatures.cpp +++ b/src/llvm-cpufeatures.cpp @@ -94,7 +94,7 @@ bool lowerCPUFeatures(Module &M) JL_NOTSAFEPOINT for (auto &F: M.functions()) { auto FN = F.getName(); - if (FN.startswith("julia.cpu.have_fma.")) { + if (FN.starts_with("julia.cpu.have_fma.")) { for (Use &U: F.uses()) { User *RU = U.getUser(); CallInst *I = cast(RU); diff --git a/src/llvm-final-gc-lowering.cpp b/src/llvm-final-gc-lowering.cpp index fe32e6d09a856..0605098bec361 100644 --- a/src/llvm-final-gc-lowering.cpp +++ b/src/llvm-final-gc-lowering.cpp @@ -1,22 +1,6 @@ // This file is a part of Julia. License is MIT: https://julialang.org/license -#include "llvm-version.h" -#include "passes.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "llvm-codegen-shared.h" -#include "julia.h" -#include "julia_internal.h" -#include "llvm-pass-helpers.h" +#include "llvm-gc-interface-passes.h" #define DEBUG_TYPE "final_gc_lowering" STATISTIC(NewGCFrameCount, "Number of lowered newGCFrameFunc intrinsics"); @@ -27,50 +11,6 @@ STATISTIC(GCAllocBytesCount, "Number of lowered GCAllocBytesFunc intrinsics"); STATISTIC(QueueGCRootCount, "Number of lowered queueGCRootFunc intrinsics"); STATISTIC(SafepointCount, "Number of lowered safepoint intrinsics"); -using namespace llvm; - -// The final GC lowering pass. This pass lowers platform-agnostic GC -// intrinsics to platform-dependent instruction sequences. The -// intrinsics it targets are those produced by the late GC frame -// lowering pass. -// -// This pass targets typical back-ends for which the standard Julia -// runtime library is available. Atypical back-ends should supply -// their own lowering pass. - -struct FinalLowerGC: private JuliaPassContext { - bool runOnFunction(Function &F); - -private: - Function *queueRootFunc; - Function *smallAllocFunc; - Function *bigAllocFunc; - Function *allocTypedFunc; - Instruction *pgcstack; - Type *T_size; - - // Lowers a `julia.new_gc_frame` intrinsic. - void lowerNewGCFrame(CallInst *target, Function &F); - - // Lowers a `julia.push_gc_frame` intrinsic. - void lowerPushGCFrame(CallInst *target, Function &F); - - // Lowers a `julia.pop_gc_frame` intrinsic. - void lowerPopGCFrame(CallInst *target, Function &F); - - // Lowers a `julia.get_gc_frame_slot` intrinsic. - void lowerGetGCFrameSlot(CallInst *target, Function &F); - - // Lowers a `julia.gc_alloc_bytes` intrinsic. - void lowerGCAllocBytes(CallInst *target, Function &F); - - // Lowers a `julia.queue_gc_root` intrinsic. - void lowerQueueGCRoot(CallInst *target, Function &F); - - // Lowers a `julia.safepoint` intrinsic. - void lowerSafepoint(CallInst *target, Function &F); -}; - void FinalLowerGC::lowerNewGCFrame(CallInst *target, Function &F) { ++NewGCFrameCount; diff --git a/src/llvm-gc-interface-passes.h b/src/llvm-gc-interface-passes.h new file mode 100644 index 0000000000000..cb485751d407b --- /dev/null +++ b/src/llvm-gc-interface-passes.h @@ -0,0 +1,413 @@ +// This file is a part of Julia. License is MIT: https://julialang.org/license + +/* + LLVM passes that may be partially modified by a third-party GC implementation. +*/ + +#include "llvm-version.h" +#include "passes.h" + +#include "llvm/IR/DerivedTypes.h" +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "llvm-codegen-shared.h" +#include "julia.h" +#include "julia_internal.h" +#include "julia_assert.h" +#include "llvm-pass-helpers.h" +#include +#include + +#ifndef LLVM_GC_PASSES_H +#define LLVM_GC_PASSES_H + +using namespace llvm; + +/* Julia GC Root Placement pass. For a general overview of the design of GC + root lowering, see the devdocs. This file is the actual implementation. + + The actual algorithm is fairly straightforward. First recall the goal of this + pass: + + Minimize the number of needed gc roots/stores to them subject to the constraint + that at every safepoint, any live gc-tracked pointer (i.e. for which there is + a path after this point that contains a use of this pointer) is in some gc slot. + + In particular, in order to understand this algorithm, it is important to + realize that the only places where rootedness matters is at safepoints. + + Now, the primary phases of the algorithm are: + + 1. Local Scan + + During this step, each Basic Block is inspected and analyzed for local + properties. In particular, we want to determine the ordering of any of + the following activities: + + - Any Def of a gc-tracked pointer. In general Defs are the results of + calls or loads from appropriate memory locations. Phi nodes and + selects do complicate this story slightly as described below. + - Any use of a gc-tracked or derived pointer. As described in the + devdocs, a use is in general one of + a) a load from a tracked/derived value + b) a store to a tracked/derived value + c) a store OF a tracked/derived value + d) a use of a value as a call operand (including operand bundles) + - Any safepoint + + Crucially, we also perform pointer numbering during the local scan, + assigning every Def a unique integer and caching the integer for each + derived pointer. This allows us to operate only on the set of Defs ( + represented by these integers) for the rest of the algorithm. We also + maintain some local utility information that is needed by later passes + (see the BBState struct for details). + + 2. Dataflow Computation + + This computation operates entirely over the function's control flow graph + and does not look into a basic block. The algorithm is essentially + textbook iterative data flow for liveness computation. However, the + data flow equations are slightly more complicated because we also + forward propagate rootedness information in addition to backpropagating + liveness. + + 3. Live Set Computation + + With the liveness information from the previous step, we can now compute, + for every safepoint, the set of values live at that particular safepoint. + There are three pieces of information being combined here: + i. Values that needed to be live due to local analysis (e.g. there + was a def, then a safepoint, then a use). This was computed during + local analysis. + ii. Values that are live across the basic block (i.e. they are live + at every safepoint within the basic block). This relies entirely + on the liveness information. + iii. Values that are now live-out from the basic block (i.e. they are + live at every safepoint following their def). During local + analysis, we keep, for every safepoint, those values that would + be live if they were live out. Here we can check if they are + actually live-out and make the appropriate additions to the live + set. + + Lastly, we also explicitly compute, for each value, the list of values + that are simultaneously live at some safepoint. This is known as an + "interference graph" and is the input to the next step. + + 4. GC Root coloring + + Two values which are not simultaneously live at a safepoint can share the + same slot. This is an important optimization, because otherwise long + functions would have exceptionally large GC slots, reducing performance + and bloating the size of the stack. Assigning values to these slots is + equivalent to doing graph coloring on the interference graph - the graph + where nodes are values and two values have an edge if they are + simultaneously live at a safepoint - which we computed in the previous + step. Now graph coloring in general is a hard problem. However, for SSA + form programs, (and most programs in general, by virtue of their + structure), the resulting interference graphs are chordal and can be + colored optimally in linear time by performing greedy coloring in a + perfect elimination order. Now, our interference graphs are likely not + entirely chordal due to some non-SSA corner cases. However, using the same + algorithm should still give a very good coloring while having sufficiently + low runtime. + + 5. JLCall frame optimizations + + Unlike earlier iterations of the gc root placement logic, jlcall frames + are no longer treated as a special case and need not necessarily be sunk + into the gc frame. Additionally, we now emit lifetime + intrinsics, so regular stack slot coloring will merge any jlcall frames + not sunk into the gc frame. Nevertheless performing such sinking can still + be profitable. Since all arguments to a jlcall are guaranteed to be live + at that call in some gc slot, we can attempt to rearrange the slots within + the gc-frame, or reuse slots not assigned at that particular location + for the gcframe. However, even without this optimization, stack frames + are at most two times larger than optimal (because regular stack coloring + can merge the jlcall allocas). + + N.B.: This step is not yet implemented. + + 6. Root placement + + This performs the actual insertion of the GCFrame pushes/pops, zeros out + the gc frame and creates the stores to the gc frame according to the + stack slot assignment computed in the previous step. GC frames stores + are generally sunk right before the first safe point that use them + (this is beneficial for code where the primary path does not have + safepoints, but some other path - e.g. the error path does). However, + if the first safepoint is not dominated by the definition (this can + happen due to the non-ssa corner cases), the store is inserted right after + the definition. + + 7. Cleanup + + This step performs necessary cleanup before passing the IR to codegen. In + particular, it removes any calls to julia_from_objref intrinsics and + removes the extra operand bundles from ccalls. In the future it could + also strip the addrspace information from all values as this + information is no longer needed. + + + There are a couple important special cases that deserve special attention: + + A. PHIs and Selects + + In general PHIs and selects are treated as separate defs for the purposes + of the algorithm and their operands as uses of those values. It is + important to consider however WHERE the uses of PHI's operands are + located. It is neither at the start of the basic block, because the values + do not dominate the block (so can't really consider them live-in), nor + at the end of the predecessor (because they are actually live out). + Instead it is best to think of those uses as living on the edge between + the appropriate predecessor and the block containing the PHI. + + Another concern is PHIs of derived values. Since we cannot simply root + these values by storing them to a GC slot, we need to insert a new, + artificial PHI that tracks the base pointers for the derived values. E.g. + in: + + A: + %Abase = load addrspace(10) *... + %Aderived = addrspacecast %Abase to addrspace(11) + B: + %Bbase = load addrspace(10) *... + %Bderived = addrspacecast %Bbase to addrspace(11) + C: + %phi = phi [%Aderived, %A + %Bderived, %B] + + we will insert another phi in C to track the relevant base pointers: + + %philift = phi [%Abase, %A + %Bbase, %B] + + We then pretend, for the purposes of numbering that %phi was derived from + %philift. Note that in order to be able to do this, we need to be able to + perform this lifting either during numbering or instruction scanning. + + B. Vectors of pointers/Union representations + + Since this pass runs very late in the pass pipeline, it runs after the + various vectorization passes. As a result, we have to potentially deal + with vectors of gc-tracked pointers. For the purposes of most of the + algorithm, we simply assign every element of the vector a separate number + and no changes are needed. However, those parts of the algorithm that + look at IR need to be aware of the possibility of encountering vectors of + pointers. + + Similarly, unions (e.g. in call returns) are represented as a struct of + a gc-tracked value and an argument selector. We simply assign a single + number to this struct and proceed as if it was a single pointer. However, + this again requires care at the IR level. + + C. Non mem2reg'd allocas + + Under some circumstances, allocas will still be present in the IR when + we get to this pass. We don't try very hard to handle this case, and + simply sink the alloca into the GCFrame. +*/ + +// 4096 bits == 64 words (64 bit words). Larger bit numbers are faster and doing something +// substantially smaller here doesn't actually save much memory because of malloc overhead. +// Too large is bad also though - 4096 was found to be a reasonable middle ground. +using LargeSparseBitVector = SparseBitVector<4096>; + +struct BBState { + // Uses in this BB + // These do not get updated after local analysis + LargeSparseBitVector Defs; + LargeSparseBitVector PhiOuts; + LargeSparseBitVector UpExposedUses; + // These get updated during dataflow + LargeSparseBitVector LiveIn; + LargeSparseBitVector LiveOut; + SmallVector Safepoints; + int TopmostSafepoint = -1; + bool HasSafepoint = false; + // Have we gone through this basic block in our local scan yet? + bool Done = false; +}; + +struct State { + Function *const F; + DominatorTree *DT; + + // The maximum assigned value number + int MaxPtrNumber; + // The maximum assigned safepoint number + int MaxSafepointNumber; + // Cache of numbers assigned to IR values. This includes caching of numbers + // for derived values + std::map AllPtrNumbering; + std::map> AllCompositeNumbering; + // The reverse of the previous maps + std::map ReversePtrNumbering; + // Neighbors in the coloring interference graph. I.e. for each value, the + // indices of other values that are used simultaneously at some safe point. + SmallVector Neighbors; + // The result of the local analysis + std::map BBStates; + + // Refinement map. If all of the values are rooted + // (-1 means an externally rooted value and -2 means a globally/permanently rooted value), + // the key is already rooted (but not the other way around). + // A value that can be refined to -2 never need any rooting or write barrier. + // A value that can be refined to -1 don't need local root but still need write barrier. + // At the end of `LocalScan` this map has a few properties + // 1. Values are either < 0 or dominates the key + // 2. Therefore this is a DAG + std::map> Refinements; + + // GC preserves map. All safepoints dominated by the map key, but not any + // of its uses need to preserve the values listed in the map value. + std::map> GCPreserves; + + // The assignment of numbers to safepoints. The indices in the map + // are indices into the next three maps which store safepoint properties + std::map SafepointNumbering; + + // Reverse mapping index -> safepoint + SmallVector ReverseSafepointNumbering; + + // Instructions that can return twice. For now, all values live at these + // instructions will get their own, dedicated GC frame slots, because they + // have unobservable control flow, so we can't be sure where they're + // actually live. All of these are also considered safepoints. + SmallVector ReturnsTwice; + + // The set of values live at a particular safepoint + SmallVector< LargeSparseBitVector , 0> LiveSets; + // Those values that - if live out from our parent basic block - are live + // at this safepoint. + SmallVector> LiveIfLiveOut; + // The set of values that are kept alive by the callee. + SmallVector> CalleeRoots; + // We don't bother doing liveness on Allocas that were not mem2reg'ed. + // they just get directly sunk into the root array. + SmallVector Allocas; + DenseMap ArrayAllocas; + DenseMap ShadowAllocas; + SmallVector, 0> TrackedStores; + State(Function &F) : F(&F), DT(nullptr), MaxPtrNumber(-1), MaxSafepointNumber(-1) {} +}; + + +struct LateLowerGCFrame: private JuliaPassContext { + function_ref GetDT; + LateLowerGCFrame(function_ref GetDT) : GetDT(GetDT) {} + +public: + bool runOnFunction(Function &F, bool *CFGModified = nullptr); + +private: + CallInst *pgcstack; + + void MaybeNoteDef(State &S, BBState &BBS, Value *Def, const ArrayRef &SafepointsSoFar, + SmallVector &&RefinedPtr = SmallVector()); + void NoteUse(State &S, BBState &BBS, Value *V, LargeSparseBitVector &Uses); + void NoteUse(State &S, BBState &BBS, Value *V) { + NoteUse(S, BBS, V, BBS.UpExposedUses); + } + + void LiftPhi(State &S, PHINode *Phi); + void LiftSelect(State &S, SelectInst *SI); + Value *MaybeExtractScalar(State &S, std::pair ValExpr, Instruction *InsertBefore); + SmallVector MaybeExtractVector(State &S, Value *BaseVec, Instruction *InsertBefore); + Value *GetPtrForNumber(State &S, unsigned Num, Instruction *InsertBefore); + + int Number(State &S, Value *V); + int NumberBase(State &S, Value *Base); + SmallVector NumberAll(State &S, Value *V); + SmallVector NumberAllBase(State &S, Value *Base); + + void NoteOperandUses(State &S, BBState &BBS, User &UI); + void MaybeTrackDst(State &S, MemTransferInst *MI); + void MaybeTrackStore(State &S, StoreInst *I); + State LocalScan(Function &F); + void ComputeLiveness(State &S); + void ComputeLiveSets(State &S); + SmallVector ColorRoots(const State &S); + void PlaceGCFrameStore(State &S, unsigned R, unsigned MinColorRoot, ArrayRef Colors, Value *GCFrame, Instruction *InsertBefore); + void PlaceGCFrameStores(State &S, unsigned MinColorRoot, ArrayRef Colors, Value *GCFrame); + void PlaceRootsAndUpdateCalls(SmallVectorImpl &Colors, State &S, std::map>); + void CleanupWriteBarriers(Function &F, State *S, const SmallVector &WriteBarriers, bool *CFGModified); + bool CleanupIR(Function &F, State *S, bool *CFGModified); + void NoteUseChain(State &S, BBState &BBS, User *TheUser); + SmallVector GetPHIRefinements(PHINode *phi, State &S); + void FixUpRefinements(ArrayRef PHINumbers, State &S); + void RefineLiveSet(LargeSparseBitVector &LS, State &S, ArrayRef CalleeRoots); + Value *EmitTagPtr(IRBuilder<> &builder, Type *T, Type *T_size, Value *V); + Value *EmitLoadTag(IRBuilder<> &builder, Type *T_size, Value *V); +}; + +// The final GC lowering pass. This pass lowers platform-agnostic GC +// intrinsics to platform-dependent instruction sequences. The +// intrinsics it targets are those produced by the late GC frame +// lowering pass. +// +// This pass targets typical back-ends for which the standard Julia +// runtime library is available. Atypical back-ends should supply +// their own lowering pass. + +struct FinalLowerGC: private JuliaPassContext { + bool runOnFunction(Function &F); + +private: + Function *queueRootFunc; + Function *smallAllocFunc; + Function *bigAllocFunc; + Function *allocTypedFunc; + Instruction *pgcstack; + Type *T_size; + + // Lowers a `julia.new_gc_frame` intrinsic. + void lowerNewGCFrame(CallInst *target, Function &F); + + // Lowers a `julia.push_gc_frame` intrinsic. + void lowerPushGCFrame(CallInst *target, Function &F); + + // Lowers a `julia.pop_gc_frame` intrinsic. + void lowerPopGCFrame(CallInst *target, Function &F); + + // Lowers a `julia.get_gc_frame_slot` intrinsic. + void lowerGetGCFrameSlot(CallInst *target, Function &F); + + // Lowers a `julia.gc_alloc_bytes` intrinsic. + void lowerGCAllocBytes(CallInst *target, Function &F); + + // Lowers a `julia.queue_gc_root` intrinsic. + void lowerQueueGCRoot(CallInst *target, Function &F); + + // Lowers a `julia.safepoint` intrinsic. + void lowerSafepoint(CallInst *target, Function &F); +}; + +#endif // LLVM_GC_PASSES_H diff --git a/src/llvm-late-gc-lowering.cpp b/src/llvm-late-gc-lowering.cpp index 65b8cdc5c7c05..e08f08860dfaf 100644 --- a/src/llvm-late-gc-lowering.cpp +++ b/src/llvm-late-gc-lowering.cpp @@ -1,367 +1,9 @@ // This file is a part of Julia. License is MIT: https://julialang.org/license -#include "llvm-version.h" -#include "passes.h" - -#include "llvm/IR/DerivedTypes.h" -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "llvm-codegen-shared.h" -#include "julia.h" -#include "julia_internal.h" -#include "julia_assert.h" -#include "llvm-pass-helpers.h" -#include -#include +#include "llvm-gc-interface-passes.h" #define DEBUG_TYPE "late_lower_gcroot" -using namespace llvm; - -/* Julia GC Root Placement pass. For a general overview of the design of GC - root lowering, see the devdocs. This file is the actual implementation. - - The actual algorithm is fairly straightforward. First recall the goal of this - pass: - - Minimize the number of needed gc roots/stores to them subject to the constraint - that at every safepoint, any live gc-tracked pointer (i.e. for which there is - a path after this point that contains a use of this pointer) is in some gc slot. - - In particular, in order to understand this algorithm, it is important to - realize that the only places where rootedness matters is at safepoints. - - Now, the primary phases of the algorithm are: - - 1. Local Scan - - During this step, each Basic Block is inspected and analyzed for local - properties. In particular, we want to determine the ordering of any of - the following activities: - - - Any Def of a gc-tracked pointer. In general Defs are the results of - calls or loads from appropriate memory locations. Phi nodes and - selects do complicate this story slightly as described below. - - Any use of a gc-tracked or derived pointer. As described in the - devdocs, a use is in general one of - a) a load from a tracked/derived value - b) a store to a tracked/derived value - c) a store OF a tracked/derived value - d) a use of a value as a call operand (including operand bundles) - - Any safepoint - - Crucially, we also perform pointer numbering during the local scan, - assigning every Def a unique integer and caching the integer for each - derived pointer. This allows us to operate only on the set of Defs ( - represented by these integers) for the rest of the algorithm. We also - maintain some local utility information that is needed by later passes - (see the BBState struct for details). - - 2. Dataflow Computation - - This computation operates entirely over the function's control flow graph - and does not look into a basic block. The algorithm is essentially - textbook iterative data flow for liveness computation. However, the - data flow equations are slightly more complicated because we also - forward propagate rootedness information in addition to backpropagating - liveness. - - 3. Live Set Computation - - With the liveness information from the previous step, we can now compute, - for every safepoint, the set of values live at that particular safepoint. - There are three pieces of information being combined here: - i. Values that needed to be live due to local analysis (e.g. there - was a def, then a safepoint, then a use). This was computed during - local analysis. - ii. Values that are live across the basic block (i.e. they are live - at every safepoint within the basic block). This relies entirely - on the liveness information. - iii. Values that are now live-out from the basic block (i.e. they are - live at every safepoint following their def). During local - analysis, we keep, for every safepoint, those values that would - be live if they were live out. Here we can check if they are - actually live-out and make the appropriate additions to the live - set. - - Lastly, we also explicitly compute, for each value, the list of values - that are simultaneously live at some safepoint. This is known as an - "interference graph" and is the input to the next step. - - 4. GC Root coloring - - Two values which are not simultaneously live at a safepoint can share the - same slot. This is an important optimization, because otherwise long - functions would have exceptionally large GC slots, reducing performance - and bloating the size of the stack. Assigning values to these slots is - equivalent to doing graph coloring on the interference graph - the graph - where nodes are values and two values have an edge if they are - simultaneously live at a safepoint - which we computed in the previous - step. Now graph coloring in general is a hard problem. However, for SSA - form programs, (and most programs in general, by virtue of their - structure), the resulting interference graphs are chordal and can be - colored optimally in linear time by performing greedy coloring in a - perfect elimination order. Now, our interference graphs are likely not - entirely chordal due to some non-SSA corner cases. However, using the same - algorithm should still give a very good coloring while having sufficiently - low runtime. - - 5. JLCall frame optimizations - - Unlike earlier iterations of the gc root placement logic, jlcall frames - are no longer treated as a special case and need not necessarily be sunk - into the gc frame. Additionally, we now emit lifetime - intrinsics, so regular stack slot coloring will merge any jlcall frames - not sunk into the gc frame. Nevertheless performing such sinking can still - be profitable. Since all arguments to a jlcall are guaranteed to be live - at that call in some gc slot, we can attempt to rearrange the slots within - the gc-frame, or reuse slots not assigned at that particular location - for the gcframe. However, even without this optimization, stack frames - are at most two times larger than optimal (because regular stack coloring - can merge the jlcall allocas). - - N.B.: This step is not yet implemented. - - 6. Root placement - - This performs the actual insertion of the GCFrame pushes/pops, zeros out - the gc frame and creates the stores to the gc frame according to the - stack slot assignment computed in the previous step. GC frames stores - are generally sunk right before the first safe point that use them - (this is beneficial for code where the primary path does not have - safepoints, but some other path - e.g. the error path does). However, - if the first safepoint is not dominated by the definition (this can - happen due to the non-ssa corner cases), the store is inserted right after - the definition. - - 7. Cleanup - - This step performs necessary cleanup before passing the IR to codegen. In - particular, it removes any calls to julia_from_objref intrinsics and - removes the extra operand bundles from ccalls. In the future it could - also strip the addrspace information from all values as this - information is no longer needed. - - - There are a couple important special cases that deserve special attention: - - A. PHIs and Selects - - In general PHIs and selects are treated as separate defs for the purposes - of the algorithm and their operands as uses of those values. It is - important to consider however WHERE the uses of PHI's operands are - located. It is neither at the start of the basic block, because the values - do not dominate the block (so can't really consider them live-in), nor - at the end of the predecessor (because they are actually live out). - Instead it is best to think of those uses as living on the edge between - the appropriate predecessor and the block containing the PHI. - - Another concern is PHIs of derived values. Since we cannot simply root - these values by storing them to a GC slot, we need to insert a new, - artificial PHI that tracks the base pointers for the derived values. E.g. - in: - - A: - %Abase = load addrspace(10) *... - %Aderived = addrspacecast %Abase to addrspace(11) - B: - %Bbase = load addrspace(10) *... - %Bderived = addrspacecast %Bbase to addrspace(11) - C: - %phi = phi [%Aderived, %A - %Bderived, %B] - - we will insert another phi in C to track the relevant base pointers: - - %philift = phi [%Abase, %A - %Bbase, %B] - - We then pretend, for the purposes of numbering that %phi was derived from - %philift. Note that in order to be able to do this, we need to be able to - perform this lifting either during numbering or instruction scanning. - - B. Vectors of pointers/Union representations - - Since this pass runs very late in the pass pipeline, it runs after the - various vectorization passes. As a result, we have to potentially deal - with vectors of gc-tracked pointers. For the purposes of most of the - algorithm, we simply assign every element of the vector a separate number - and no changes are needed. However, those parts of the algorithm that - look at IR need to be aware of the possibility of encountering vectors of - pointers. - - Similarly, unions (e.g. in call returns) are represented as a struct of - a gc-tracked value and an argument selector. We simply assign a single - number to this struct and proceed as if it was a single pointer. However, - this again requires care at the IR level. - - C. Non mem2reg'd allocas - - Under some circumstances, allocas will still be present in the IR when - we get to this pass. We don't try very hard to handle this case, and - simply sink the alloca into the GCFrame. -*/ - -// 4096 bits == 64 words (64 bit words). Larger bit numbers are faster and doing something -// substantially smaller here doesn't actually save much memory because of malloc overhead. -// Too large is bad also though - 4096 was found to be a reasonable middle ground. -using LargeSparseBitVector = SparseBitVector<4096>; - -struct BBState { - // Uses in this BB - // These do not get updated after local analysis - LargeSparseBitVector Defs; - LargeSparseBitVector PhiOuts; - LargeSparseBitVector UpExposedUses; - // These get updated during dataflow - LargeSparseBitVector LiveIn; - LargeSparseBitVector LiveOut; - SmallVector Safepoints; - int TopmostSafepoint = -1; - bool HasSafepoint = false; - // Have we gone through this basic block in our local scan yet? - bool Done = false; -}; - -struct State { - Function *const F; - DominatorTree *DT; - - // The maximum assigned value number - int MaxPtrNumber; - // The maximum assigned safepoint number - int MaxSafepointNumber; - // Cache of numbers assigned to IR values. This includes caching of numbers - // for derived values - std::map AllPtrNumbering; - std::map> AllCompositeNumbering; - // The reverse of the previous maps - std::map ReversePtrNumbering; - // Neighbors in the coloring interference graph. I.e. for each value, the - // indices of other values that are used simultaneously at some safe point. - SmallVector Neighbors; - // The result of the local analysis - std::map BBStates; - - // Refinement map. If all of the values are rooted - // (-1 means an externally rooted value and -2 means a globally/permanently rooted value), - // the key is already rooted (but not the other way around). - // A value that can be refined to -2 never need any rooting or write barrier. - // A value that can be refined to -1 don't need local root but still need write barrier. - // At the end of `LocalScan` this map has a few properties - // 1. Values are either < 0 or dominates the key - // 2. Therefore this is a DAG - std::map> Refinements; - - // GC preserves map. All safepoints dominated by the map key, but not any - // of its uses need to preserve the values listed in the map value. - std::map> GCPreserves; - - // The assignment of numbers to safepoints. The indices in the map - // are indices into the next three maps which store safepoint properties - std::map SafepointNumbering; - - // Reverse mapping index -> safepoint - SmallVector ReverseSafepointNumbering; - - // Instructions that can return twice. For now, all values live at these - // instructions will get their own, dedicated GC frame slots, because they - // have unobservable control flow, so we can't be sure where they're - // actually live. All of these are also considered safepoints. - SmallVector ReturnsTwice; - - // The set of values live at a particular safepoint - SmallVector< LargeSparseBitVector , 0> LiveSets; - // Those values that - if live out from our parent basic block - are live - // at this safepoint. - SmallVector> LiveIfLiveOut; - // The set of values that are kept alive by the callee. - SmallVector> CalleeRoots; - // We don't bother doing liveness on Allocas that were not mem2reg'ed. - // they just get directly sunk into the root array. - SmallVector Allocas; - DenseMap ArrayAllocas; - DenseMap ShadowAllocas; - SmallVector, 0> TrackedStores; - State(Function &F) : F(&F), DT(nullptr), MaxPtrNumber(-1), MaxSafepointNumber(-1) {} -}; - - -struct LateLowerGCFrame: private JuliaPassContext { - function_ref GetDT; - LateLowerGCFrame(function_ref GetDT) : GetDT(GetDT) {} - -public: - bool runOnFunction(Function &F, bool *CFGModified = nullptr); - -private: - CallInst *pgcstack; - - void MaybeNoteDef(State &S, BBState &BBS, Value *Def, const ArrayRef &SafepointsSoFar, - SmallVector &&RefinedPtr = SmallVector()); - void NoteUse(State &S, BBState &BBS, Value *V, LargeSparseBitVector &Uses); - void NoteUse(State &S, BBState &BBS, Value *V) { - NoteUse(S, BBS, V, BBS.UpExposedUses); - } - - void LiftPhi(State &S, PHINode *Phi); - void LiftSelect(State &S, SelectInst *SI); - Value *MaybeExtractScalar(State &S, std::pair ValExpr, Instruction *InsertBefore); - SmallVector MaybeExtractVector(State &S, Value *BaseVec, Instruction *InsertBefore); - Value *GetPtrForNumber(State &S, unsigned Num, Instruction *InsertBefore); - - int Number(State &S, Value *V); - int NumberBase(State &S, Value *Base); - SmallVector NumberAll(State &S, Value *V); - SmallVector NumberAllBase(State &S, Value *Base); - - void NoteOperandUses(State &S, BBState &BBS, User &UI); - void MaybeTrackDst(State &S, MemTransferInst *MI); - void MaybeTrackStore(State &S, StoreInst *I); - State LocalScan(Function &F); - void ComputeLiveness(State &S); - void ComputeLiveSets(State &S); - SmallVector ColorRoots(const State &S); - void PlaceGCFrameStore(State &S, unsigned R, unsigned MinColorRoot, ArrayRef Colors, Value *GCFrame, Instruction *InsertBefore); - void PlaceGCFrameStores(State &S, unsigned MinColorRoot, ArrayRef Colors, Value *GCFrame); - void PlaceRootsAndUpdateCalls(SmallVectorImpl &Colors, State &S, std::map>); - void CleanupWriteBarriers(Function &F, State *S, const SmallVector &WriteBarriers, bool *CFGModified); - bool CleanupIR(Function &F, State *S, bool *CFGModified); - void NoteUseChain(State &S, BBState &BBS, User *TheUser); - SmallVector GetPHIRefinements(PHINode *phi, State &S); - void FixUpRefinements(ArrayRef PHINumbers, State &S); - void RefineLiveSet(LargeSparseBitVector &LS, State &S, ArrayRef CalleeRoots); - Value *EmitTagPtr(IRBuilder<> &builder, Type *T, Type *T_size, Value *V); - Value *EmitLoadTag(IRBuilder<> &builder, Type *T_size, Value *V); -}; - static unsigned getValueAddrSpace(Value *V) { return V->getType()->getPointerAddressSpace(); } diff --git a/src/llvm-multiversioning.cpp b/src/llvm-multiversioning.cpp index 08600e24490b1..d544f182637b9 100644 --- a/src/llvm-multiversioning.cpp +++ b/src/llvm-multiversioning.cpp @@ -100,11 +100,11 @@ static uint32_t collect_func_info(Function &F, const Triple &TT, bool &has_vecca } if (auto callee = call->getCalledFunction()) { auto name = callee->getName(); - if (name.startswith("llvm.muladd.") || name.startswith("llvm.fma.")) { + if (name.starts_with("llvm.muladd.") || name.starts_with("llvm.fma.")) { flag |= JL_TARGET_CLONE_MATH; } - else if (name.startswith("julia.cpu.")) { - if (name.startswith("julia.cpu.have_fma.")) { + else if (name.starts_with("julia.cpu.")) { + if (name.starts_with("julia.cpu.have_fma.")) { // for some platforms we know they always do (or don't) support // FMA. in those cases we don't need to clone the function. // always_have_fma returns an optional diff --git a/src/llvm-simdloop.cpp b/src/llvm-simdloop.cpp index f29802b438e1e..07afa8c930deb 100644 --- a/src/llvm-simdloop.cpp +++ b/src/llvm-simdloop.cpp @@ -177,7 +177,7 @@ static bool processLoop(Loop &L, OptimizationRemarkEmitter &ORE, ScalarEvolution const MDString *S = dyn_cast(Op); if (S) { LLVM_DEBUG(dbgs() << "LSL: found " << S->getString() << "\n"); - if (S->getString().startswith("julia")) { + if (S->getString().starts_with("julia")) { if (S->getString().equals("julia.simdloop")) simd = true; if (S->getString().equals("julia.ivdep")) diff --git a/src/llvm_api.cpp b/src/llvm_api.cpp index d56fb3a0497fa..e98c375b711b3 100644 --- a/src/llvm_api.cpp +++ b/src/llvm_api.cpp @@ -21,6 +21,7 @@ #include #include +#if JL_LLVM_VERSION < 180000 namespace llvm { namespace orc { class OrcV2CAPIHelper { @@ -38,7 +39,7 @@ class OrcV2CAPIHelper { }; } // namespace orc } // namespace llvm - +#endif typedef struct JLOpaqueJuliaOJIT *JuliaOJITRef; typedef struct LLVMOrcOpaqueIRCompileLayer *LLVMOrcIRCompileLayerRef; @@ -46,8 +47,13 @@ typedef struct LLVMOrcOpaqueIRCompileLayer *LLVMOrcIRCompileLayerRef; DEFINE_SIMPLE_CONVERSION_FUNCTIONS(JuliaOJIT, JuliaOJITRef) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(orc::JITDylib, LLVMOrcJITDylibRef) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(orc::ExecutionSession, LLVMOrcExecutionSessionRef) +#if JL_LLVM_VERSION >= 180000 +DEFINE_SIMPLE_CONVERSION_FUNCTIONS(orc::SymbolStringPoolEntryUnsafe::PoolEntry, + LLVMOrcSymbolStringPoolEntryRef) +#else DEFINE_SIMPLE_CONVERSION_FUNCTIONS(orc::OrcV2CAPIHelper::PoolEntry, LLVMOrcSymbolStringPoolEntryRef) +#endif DEFINE_SIMPLE_CONVERSION_FUNCTIONS(orc::IRCompileLayer, LLVMOrcIRCompileLayerRef) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(orc::MaterializationResponsibility, LLVMOrcMaterializationResponsibilityRef) @@ -113,7 +119,11 @@ JL_DLLEXPORT_CODEGEN LLVMOrcSymbolStringPoolEntryRef JLJITMangleAndIntern_impl(JuliaOJITRef JIT, const char *Name) { +#if JL_LLVM_VERSION >= 180000 + return wrap(orc::SymbolStringPoolEntryUnsafe::take(unwrap(JIT)->mangle(Name)).rawPtr()); +#else return wrap(orc::OrcV2CAPIHelper::moveFromSymbolStringPtr(unwrap(JIT)->mangle(Name))); +#endif } JL_DLLEXPORT_CODEGEN const char * diff --git a/src/method.c b/src/method.c index 549575286bc7e..d890489c390f9 100644 --- a/src/method.c +++ b/src/method.c @@ -491,6 +491,8 @@ jl_code_info_t *jl_new_code_info_from_ir(jl_expr_t *ir) if (noub_if_noinbounds) li->purity.overrides.ipo_noub_if_noinbounds = noub_if_noinbounds; int8_t consistent_overlay = jl_unbox_bool(jl_exprarg(ma, 9)); if (consistent_overlay) li->purity.overrides.ipo_consistent_overlay = consistent_overlay; + int8_t nortcall = jl_unbox_bool(jl_exprarg(ma, 10)); + if (nortcall) li->purity.overrides.ipo_nortcall = nortcall; } } else diff --git a/src/options.h b/src/options.h index 5da9bf2b1a740..800be866183b0 100644 --- a/src/options.h +++ b/src/options.h @@ -110,7 +110,7 @@ #if defined(_COMPILER_ASAN_ENABLED_) || defined(_COMPILER_MSAN_ENABLED_) #define JL_STACK_SIZE (64*1024*1024) #elif defined(_P64) -#define JL_STACK_SIZE (4*1024*1024) +#define JL_STACK_SIZE (8*1024*1024) #else #define JL_STACK_SIZE (2*1024*1024) #endif diff --git a/src/pipeline.cpp b/src/pipeline.cpp index f0dde6aa59a40..236be179e12c9 100644 --- a/src/pipeline.cpp +++ b/src/pipeline.cpp @@ -19,18 +19,6 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include #include @@ -40,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -76,6 +65,8 @@ #include #include #include +#include +#include #include #include #include @@ -618,65 +609,6 @@ static void buildPipeline(ModulePassManager &MPM, PassBuilder *PB, OptimizationL MPM.addPass(AfterOptimizationMarkerPass()); } -struct PipelineConfig { - int Speedup; - int Size; - int lower_intrinsics; - int dump_native; - int external_use; - int llvm_only; - int always_inline; - int enable_early_simplifications; - int enable_early_optimizations; - int enable_scalar_optimizations; - int enable_loop_optimizations; - int enable_vector_pipeline; - int remove_ni; - int cleanup; - int warn_missed_transformations; -}; - -extern "C" JL_DLLEXPORT_CODEGEN void jl_build_newpm_pipeline_impl(void *MPM, void *PB, PipelineConfig* config) JL_NOTSAFEPOINT -{ - OptimizationLevel O; - switch (config->Size) { - case 1: - O = OptimizationLevel::Os; - break; - default: - O = OptimizationLevel::Oz; - break; - case 0: - switch (config->Speedup) { - case 0: - O = OptimizationLevel::O0; - break; - case 1: - O = OptimizationLevel::O1; - break; - case 2: - O = OptimizationLevel::O2; - break; - default: - O = OptimizationLevel::O3; - break; - } - } - buildPipeline(*reinterpret_cast(MPM), reinterpret_cast(PB), O, - OptimizationOptions{!!config->lower_intrinsics, - !!config->dump_native, - !!config->external_use, - !!config->llvm_only, - !!config->always_inline, - !!config->enable_early_simplifications, - !!config->enable_early_optimizations, - !!config->enable_scalar_optimizations, - !!config->enable_loop_optimizations, - !!config->enable_vector_pipeline, - !!config->remove_ni, - !!config->cleanup, - !!config->warn_missed_transformations}); -} #undef JULIA_PASS @@ -874,6 +806,14 @@ static Optional> parseJuliaPip OPTION(dump_native), OPTION(external_use), OPTION(llvm_only), + OPTION(always_inline), + OPTION(enable_early_simplifications), + OPTION(enable_early_optimizations), + OPTION(enable_scalar_optimizations), + OPTION(enable_loop_optimizations), + OPTION(enable_vector_pipeline), + OPTION(remove_ni), + OPTION(cleanup), OPTION(warn_missed_transformations) #undef OPTION }; diff --git a/src/processor_arm.cpp b/src/processor_arm.cpp index b9ad5e68111e5..d28e527ed44e8 100644 --- a/src/processor_arm.cpp +++ b/src/processor_arm.cpp @@ -839,7 +839,7 @@ template static inline bool try_read_procfs_line(llvm::StringRef line, const char *prefix, T &out, bool &flag, F &&reset) { - if (!line.startswith(prefix)) + if (!line.starts_with(prefix)) return false; if (flag) reset(); diff --git a/src/scheduler.c b/src/scheduler.c index 2c7dbd63ef4a4..3505e935afcf6 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -7,7 +7,6 @@ #include "julia.h" #include "julia_internal.h" -#include "gc.h" #include "threading.h" #ifdef __cplusplus @@ -32,7 +31,7 @@ static const int16_t sleeping_like_the_dead JL_UNUSED = 2; // a running count of how many threads are currently not_sleeping // plus a running count of the number of in-flight wake-ups // n.b. this may temporarily exceed jl_n_threads -static _Atomic(int) nrunning = 0; +_Atomic(int) n_threads_running = 0; // invariant: No thread is ever asleep unless sleep_check_state is sleeping (or we have a wakeup signal pending). // invariant: Any particular thread is not asleep unless that thread's sleep_check_state is sleeping. @@ -112,79 +111,6 @@ void jl_init_threadinginfra(void) void JL_NORETURN jl_finish_task(jl_task_t *ct); -static inline int may_mark(void) JL_NOTSAFEPOINT -{ - return (jl_atomic_load(&gc_n_threads_marking) > 0); -} - -static inline int may_sweep(jl_ptls_t ptls) JL_NOTSAFEPOINT -{ - return (jl_atomic_load(&ptls->gc_tls.gc_sweeps_requested) > 0); -} - -// parallel gc thread function -void jl_parallel_gc_threadfun(void *arg) -{ - jl_threadarg_t *targ = (jl_threadarg_t*)arg; - - // initialize this thread (set tid and create heap) - jl_ptls_t ptls = jl_init_threadtls(targ->tid); - void *stack_lo, *stack_hi; - jl_init_stack_limits(0, &stack_lo, &stack_hi); - // warning: this changes `jl_current_task`, so be careful not to call that from this function - jl_task_t *ct = jl_init_root_task(ptls, stack_lo, stack_hi); - JL_GC_PROMISE_ROOTED(ct); - (void)jl_atomic_fetch_add_relaxed(&nrunning, -1); - // wait for all threads - jl_gc_state_set(ptls, JL_GC_PARALLEL_COLLECTOR_THREAD, JL_GC_STATE_UNSAFE); - uv_barrier_wait(targ->barrier); - - // free the thread argument here - free(targ); - - while (1) { - uv_mutex_lock(&gc_threads_lock); - while (!may_mark() && !may_sweep(ptls)) { - uv_cond_wait(&gc_threads_cond, &gc_threads_lock); - } - uv_mutex_unlock(&gc_threads_lock); - assert(jl_atomic_load_relaxed(&ptls->gc_state) == JL_GC_PARALLEL_COLLECTOR_THREAD); - gc_mark_loop_parallel(ptls, 0); - if (may_sweep(ptls)) { - assert(jl_atomic_load_relaxed(&ptls->gc_state) == JL_GC_PARALLEL_COLLECTOR_THREAD); - gc_sweep_pool_parallel(ptls); - jl_atomic_fetch_add(&ptls->gc_tls.gc_sweeps_requested, -1); - } - } -} - -// concurrent gc thread function -void jl_concurrent_gc_threadfun(void *arg) -{ - jl_threadarg_t *targ = (jl_threadarg_t*)arg; - - // initialize this thread (set tid and create heap) - jl_ptls_t ptls = jl_init_threadtls(targ->tid); - void *stack_lo, *stack_hi; - jl_init_stack_limits(0, &stack_lo, &stack_hi); - // warning: this changes `jl_current_task`, so be careful not to call that from this function - jl_task_t *ct = jl_init_root_task(ptls, stack_lo, stack_hi); - JL_GC_PROMISE_ROOTED(ct); - (void)jl_atomic_fetch_add_relaxed(&nrunning, -1); - // wait for all threads - jl_gc_state_set(ptls, JL_GC_CONCURRENT_COLLECTOR_THREAD, JL_GC_STATE_UNSAFE); - uv_barrier_wait(targ->barrier); - - // free the thread argument here - free(targ); - - while (1) { - assert(jl_atomic_load_relaxed(&ptls->gc_state) == JL_GC_CONCURRENT_COLLECTOR_THREAD); - uv_sem_wait(&gc_sweep_assists_needed); - gc_free_pages(); - } -} - // thread function: used by all mutator threads except the main thread void jl_threadfun(void *arg) { @@ -218,9 +144,9 @@ void jl_init_thread_scheduler(jl_ptls_t ptls) JL_NOTSAFEPOINT // record that there is now another thread that may be used to schedule work // we will decrement this again in scheduler_delete_thread, only slightly // in advance of pthread_join (which hopefully itself also had been - // adopted by now and is included in nrunning too) - (void)jl_atomic_fetch_add_relaxed(&nrunning, 1); - // n.b. this is the only point in the code where we ignore the invariants on the ordering of nrunning + // adopted by now and is included in n_threads_running too) + (void)jl_atomic_fetch_add_relaxed(&n_threads_running, 1); + // n.b. this is the only point in the code where we ignore the invariants on the ordering of n_threads_running // since we are being initialized from foreign code, we could not necessarily have expected or predicted that to happen } @@ -280,7 +206,7 @@ static int set_not_sleeping(jl_ptls_t ptls) JL_NOTSAFEPOINT return 1; } } - int wasrunning = jl_atomic_fetch_add_relaxed(&nrunning, -1); // consume in-flight wakeup + int wasrunning = jl_atomic_fetch_add_relaxed(&n_threads_running, -1); // consume in-flight wakeup assert(wasrunning > 1); (void)wasrunning; return 0; } @@ -292,7 +218,7 @@ static int wake_thread(int16_t tid) JL_NOTSAFEPOINT if (jl_atomic_load_relaxed(&ptls2->sleep_check_state) != not_sleeping) { int8_t state = sleeping; if (jl_atomic_cmpswap_relaxed(&ptls2->sleep_check_state, &state, not_sleeping)) { - int wasrunning = jl_atomic_fetch_add_relaxed(&nrunning, 1); // increment in-flight wakeup count + int wasrunning = jl_atomic_fetch_add_relaxed(&n_threads_running, 1); // increment in-flight wakeup count assert(wasrunning); (void)wasrunning; JL_PROBE_RT_SLEEP_CHECK_WAKE(ptls2, state); uv_mutex_lock(&ptls2->sleep_lock); @@ -323,11 +249,11 @@ JL_DLLEXPORT void jl_wakeup_thread(int16_t tid) JL_NOTSAFEPOINT JULIA_DEBUG_SLEEPWAKE( wakeup_enter = cycleclock() ); if (tid == self || tid == -1) { // we're already awake, but make sure we'll exit uv_run - // and that nrunning is updated if this is now considered in-flight + // and that n_threads_running is updated if this is now considered in-flight jl_ptls_t ptls = ct->ptls; if (jl_atomic_load_relaxed(&ptls->sleep_check_state) != not_sleeping) { if (jl_atomic_exchange_relaxed(&ptls->sleep_check_state, not_sleeping) != not_sleeping) { - int wasrunning = jl_atomic_fetch_add_relaxed(&nrunning, 1); + int wasrunning = jl_atomic_fetch_add_relaxed(&n_threads_running, 1); assert(wasrunning); (void)wasrunning; JL_PROBE_RT_SLEEP_CHECK_WAKEUP(ptls); } @@ -548,8 +474,8 @@ JL_DLLEXPORT jl_task_t *jl_task_get_next(jl_value_t *trypoptask, jl_value_t *q, } // any thread which wants us running again will have to observe - // sleep_check_state==sleeping and increment nrunning for us - int wasrunning = jl_atomic_fetch_add_relaxed(&nrunning, -1); + // sleep_check_state==sleeping and increment n_threads_running for us + int wasrunning = jl_atomic_fetch_add_relaxed(&n_threads_running, -1); assert(wasrunning); isrunning = 0; if (wasrunning == 1) { @@ -573,8 +499,8 @@ JL_DLLEXPORT jl_task_t *jl_task_get_next(jl_value_t *trypoptask, jl_value_t *q, while (may_sleep(ptls)) { if (ptls->tid == 0) { task = wait_empty; - if (task && jl_atomic_load_relaxed(&nrunning) == 0) { - wasrunning = jl_atomic_fetch_add_relaxed(&nrunning, 1); + if (task && jl_atomic_load_relaxed(&n_threads_running) == 0) { + wasrunning = jl_atomic_fetch_add_relaxed(&n_threads_running, 1); assert(!wasrunning); wasrunning = !set_not_sleeping(ptls); assert(!wasrunning); @@ -585,11 +511,11 @@ JL_DLLEXPORT jl_task_t *jl_task_get_next(jl_value_t *trypoptask, jl_value_t *q, } task = NULL; } - // else should we warn the user of certain deadlock here if tid == 0 && nrunning == 0? + // else should we warn the user of certain deadlock here if tid == 0 && n_threads_running == 0? uv_cond_wait(&ptls->wake_signal, &ptls->sleep_lock); } assert(jl_atomic_load_relaxed(&ptls->sleep_check_state) == not_sleeping); - assert(jl_atomic_load_relaxed(&nrunning)); + assert(jl_atomic_load_relaxed(&n_threads_running)); start_cycles = 0; uv_mutex_unlock(&ptls->sleep_lock); JULIA_DEBUG_SLEEPWAKE( ptls->sleep_leave = cycleclock() ); @@ -603,7 +529,7 @@ JL_DLLEXPORT jl_task_t *jl_task_get_next(jl_value_t *trypoptask, jl_value_t *q, JL_CATCH { // probably SIGINT, but possibly a user mistake in trypoptask if (!isrunning) - jl_atomic_fetch_add_relaxed(&nrunning, 1); + jl_atomic_fetch_add_relaxed(&n_threads_running, 1); set_not_sleeping(ptls); jl_rethrow(); } @@ -622,7 +548,7 @@ void scheduler_delete_thread(jl_ptls_t ptls) JL_NOTSAFEPOINT int notsleeping = jl_atomic_exchange_relaxed(&ptls->sleep_check_state, sleeping_like_the_dead) == not_sleeping; jl_fence(); if (notsleeping) { - if (jl_atomic_load_relaxed(&nrunning) == 1) { + if (jl_atomic_load_relaxed(&n_threads_running) == 1) { jl_ptls_t ptls2 = jl_atomic_load_relaxed(&jl_all_tls_states)[jl_atomic_load_relaxed(&io_loop_tid)]; // This was the last running thread, and there is no thread with !may_sleep // so make sure tid 0 is notified to check wait_empty @@ -632,10 +558,10 @@ void scheduler_delete_thread(jl_ptls_t ptls) JL_NOTSAFEPOINT } } else { - jl_atomic_fetch_add_relaxed(&nrunning, 1); + jl_atomic_fetch_add_relaxed(&n_threads_running, 1); } jl_wakeup_thread(0); // force thread 0 to see that we do not have the IO lock (and am dead) - jl_atomic_fetch_add_relaxed(&nrunning, -1); + jl_atomic_fetch_add_relaxed(&n_threads_running, -1); } #ifdef __cplusplus diff --git a/src/signals-mach.c b/src/signals-mach.c index 129cb8afb542f..c31b6d506b4e6 100644 --- a/src/signals-mach.c +++ b/src/signals-mach.c @@ -738,16 +738,16 @@ void *mach_profile_listener(void *arg) #endif jl_ptls_t ptls = jl_atomic_load_relaxed(&jl_all_tls_states)[i]; - // store threadid but add 1 as 0 is preserved to indicate end of block + // META_OFFSET_THREADID store threadid but add 1 as 0 is preserved to indicate end of block bt_data_prof[bt_size_cur++].uintptr = ptls->tid + 1; - // store task id (never null) + // META_OFFSET_TASKID store task id (never null) bt_data_prof[bt_size_cur++].jlvalue = (jl_value_t*)jl_atomic_load_relaxed(&ptls->current_task); - // store cpu cycle clock + // META_OFFSET_CPUCYCLECLOCK store cpu cycle clock bt_data_prof[bt_size_cur++].uintptr = cycleclock(); - // store whether thread is sleeping but add 1 as 0 is preserved to indicate end of block + // META_OFFSET_SLEEPSTATE store whether thread is sleeping but add 1 as 0 is preserved to indicate end of block bt_data_prof[bt_size_cur++].uintptr = jl_atomic_load_relaxed(&ptls->sleep_check_state) + 1; // Mark the end of this block with two 0's diff --git a/src/signals-unix.c b/src/signals-unix.c index aa4d1626a4305..5e79fd5a2e29e 100644 --- a/src/signals-unix.c +++ b/src/signals-unix.c @@ -965,16 +965,16 @@ static void *signal_listener(void *arg) jl_ptls_t ptls2 = jl_atomic_load_relaxed(&jl_all_tls_states)[i]; - // store threadid but add 1 as 0 is preserved to indicate end of block + // META_OFFSET_THREADID store threadid but add 1 as 0 is preserved to indicate end of block bt_data_prof[bt_size_cur++].uintptr = ptls2->tid + 1; - // store task id (never null) + // META_OFFSET_TASKID store task id (never null) bt_data_prof[bt_size_cur++].jlvalue = (jl_value_t*)jl_atomic_load_relaxed(&ptls2->current_task); - // store cpu cycle clock + // META_OFFSET_CPUCYCLECLOCK store cpu cycle clock bt_data_prof[bt_size_cur++].uintptr = cycleclock(); - // store whether thread is sleeping but add 1 as 0 is preserved to indicate end of block + // META_OFFSET_SLEEPSTATE store whether thread is sleeping but add 1 as 0 is preserved to indicate end of block bt_data_prof[bt_size_cur++].uintptr = jl_atomic_load_relaxed(&ptls2->sleep_check_state) + 1; // Mark the end of this block with two 0's @@ -1011,12 +1011,12 @@ static void *signal_listener(void *arg) else if (critical) { // critical in this case actually means SIGINFO request #ifndef SIGINFO // SIGINFO already prints something similar automatically - int nrunning = 0; + int n_threads_running = 0; for (int idx = nthreads; idx-- > 0; ) { jl_ptls_t ptls2 = jl_atomic_load_relaxed(&jl_all_tls_states)[idx]; - nrunning += !jl_atomic_load_relaxed(&ptls2->sleep_check_state); + n_threads_running += !jl_atomic_load_relaxed(&ptls2->sleep_check_state); } - jl_safe_printf("\ncmd: %s %d running %d of %d\n", jl_options.julia_bin ? jl_options.julia_bin : "julia", uv_os_getpid(), nrunning, nthreads); + jl_safe_printf("\ncmd: %s %d running %d of %d\n", jl_options.julia_bin ? jl_options.julia_bin : "julia", uv_os_getpid(), n_threads_running, nthreads); #endif jl_safe_printf("\nsignal (%d): %s\n", sig, strsignal(sig)); diff --git a/src/signals-win.c b/src/signals-win.c index 4c31df766f3f1..d7288b5d365d8 100644 --- a/src/signals-win.c +++ b/src/signals-win.c @@ -421,16 +421,16 @@ static DWORD WINAPI profile_bt( LPVOID lparam ) jl_ptls_t ptls = jl_atomic_load_relaxed(&jl_all_tls_states)[0]; // given only profiling hMainThread - // store threadid but add 1 as 0 is preserved to indicate end of block + // META_OFFSET_THREADID store threadid but add 1 as 0 is preserved to indicate end of block bt_data_prof[bt_size_cur++].uintptr = ptls->tid + 1; - // store task id (never null) + // META_OFFSET_TASKID store task id (never null) bt_data_prof[bt_size_cur++].jlvalue = (jl_value_t*)jl_atomic_load_relaxed(&ptls->current_task); - // store cpu cycle clock + // META_OFFSET_CPUCYCLECLOCK store cpu cycle clock bt_data_prof[bt_size_cur++].uintptr = cycleclock(); - // store whether thread is sleeping but add 1 as 0 is preserved to indicate end of block + // META_OFFSET_SLEEPSTATE store whether thread is sleeping but add 1 as 0 is preserved to indicate end of block bt_data_prof[bt_size_cur++].uintptr = jl_atomic_load_relaxed(&ptls->sleep_check_state) + 1; // Mark the end of this block with two 0's diff --git a/src/stackwalk.c b/src/stackwalk.c index 7e4a04f6b77e4..a63694e7c3b0c 100644 --- a/src/stackwalk.c +++ b/src/stackwalk.c @@ -5,7 +5,7 @@ utilities for walking the stack and looking up information about code addresses */ #include -#include "gc.h" +#include "gc-stock.h" #include "julia.h" #include "julia_internal.h" #include "threading.h" diff --git a/src/subtype.c b/src/subtype.c index 3340abfc4bafc..4118bbeab649b 100644 --- a/src/subtype.c +++ b/src/subtype.c @@ -65,7 +65,6 @@ typedef struct jl_varbinding_t { jl_value_t *lb; jl_value_t *ub; int8_t right; // whether this variable came from the right side of `A <: B` - int8_t occurs; // occurs in any position int8_t occurs_inv; // occurs in invariant position int8_t occurs_cov; // # of occurrences in covariant position int8_t concrete; // 1 if another variable has a constraint forcing this one to be concrete @@ -179,7 +178,7 @@ static int current_env_length(jl_stenv_t *e) typedef struct { int8_t *buf; int rdepth; - int8_t _space[32]; // == 8 * 4 + int8_t _space[24]; // == 8 * 3 jl_gcframe_t gcframe; jl_value_t *roots[24]; // == 8 * 3 } jl_savedenv_t; @@ -208,7 +207,6 @@ static void re_save_env(jl_stenv_t *e, jl_savedenv_t *se, int root) roots[i++] = v->ub; roots[i++] = (jl_value_t*)v->innervars; } - se->buf[j++] = v->occurs; se->buf[j++] = v->occurs_inv; se->buf[j++] = v->occurs_cov; se->buf[j++] = v->max_offset; @@ -243,7 +241,7 @@ static void alloc_env(jl_stenv_t *e, jl_savedenv_t *se, int root) ct->gcstack = &se->gcframe; } } - se->buf = (len > 8 ? (int8_t*)malloc_s(len * 4) : se->_space); + se->buf = (len > 8 ? (int8_t*)malloc_s(len * 3) : se->_space); #ifdef __clang_gcanalyzer__ memset(se->buf, 0, len * 3); #endif @@ -290,7 +288,6 @@ static void restore_env(jl_stenv_t *e, jl_savedenv_t *se, int root) JL_NOTSAFEPO v->ub = roots[i++]; v->innervars = (jl_array_t*)roots[i++]; } - v->occurs = se->buf[j++]; v->occurs_inv = se->buf[j++]; v->occurs_cov = se->buf[j++]; v->max_offset = se->buf[j++]; @@ -302,15 +299,6 @@ static void restore_env(jl_stenv_t *e, jl_savedenv_t *se, int root) JL_NOTSAFEPO memset(&e->envout[e->envidx], 0, (e->envsz - e->envidx)*sizeof(void*)); } -static void clean_occurs(jl_stenv_t *e) -{ - jl_varbinding_t *v = e->vars; - while (v) { - v->occurs = 0; - v = v->prev; - } -} - #define flip_offset(e) ((e)->Loffset *= -1) // type utilities @@ -599,6 +587,8 @@ static jl_value_t *simple_meet(jl_value_t *a, jl_value_t *b, int overesi) static int subtype(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, int param); +#define has_next_union_state(e, R) ((((R) ? &(e)->Runions : &(e)->Lunions)->more) != 0) + static int next_union_state(jl_stenv_t *e, int8_t R) JL_NOTSAFEPOINT { jl_unionstate_t *state = R ? &e->Runions : &e->Lunions; @@ -679,8 +669,6 @@ static int subtype_left_var(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, int par // of determining whether the variable is concrete. static void record_var_occurrence(jl_varbinding_t *vb, jl_stenv_t *e, int param) JL_NOTSAFEPOINT { - if (vb != NULL) - vb->occurs = 1; if (vb != NULL && param) { // saturate counters at 2; we don't need values bigger than that if (param == 2 && e->invdepth > vb->depth0) { @@ -915,7 +903,7 @@ static jl_unionall_t *unalias_unionall(jl_unionall_t *u, jl_stenv_t *e) static int subtype_unionall(jl_value_t *t, jl_unionall_t *u, jl_stenv_t *e, int8_t R, int param) { u = unalias_unionall(u, e); - jl_varbinding_t vb = { u->var, u->var->lb, u->var->ub, R, 0, 0, 0, 0, 0, 0, 0, 0, 0, + jl_varbinding_t vb = { u->var, u->var->lb, u->var->ub, R, 0, 0, 0, 0, 0, 0, 0, 0, e->invdepth, NULL, e->vars }; JL_GC_PUSH4(&u, &vb.lb, &vb.ub, &vb.innervars); e->vars = &vb; @@ -1324,7 +1312,21 @@ static int try_subtype_by_bounds(jl_value_t *a, jl_value_t *b, jl_stenv_t *e); static int subtype(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, int param) { if (jl_is_uniontype(x)) { - if (x == y) return 1; + if (obviously_egal(x, y)) + return 1; + if (e->Runions.depth == 0 && jl_is_typevar(y) && !jl_has_free_typevars(x) && !jl_has_free_typevars(((jl_tvar_t*)y)->ub)) { + // Similar to fast path for repeated elements: if there have been no outer + // unions on the right, and the right side is a typevar, then we can handle the + // typevar first before picking a union element, under the theory that it may + // be easy to match or reject this whole union in comparing and setting the lb + // and ub of the variable binding, without needing to examine each element. + // However, if x contains any free typevars, then each element with a free + // typevar must be handled separately from the union of all elements without + // free typevars, since the typevars presence might lead to those elements + // getting eliminated (omit_bad_union) or degenerate (Union{Ptr{T}, Ptr}) or + // combined (Union{T, S} where {T, S <: T}). + return subtype_var((jl_tvar_t*)y, x, e, 1, param); + } x = pick_union_element(x, e, 0); } if (jl_is_uniontype(y)) { @@ -3312,7 +3314,7 @@ static jl_value_t *intersect_unionall(jl_value_t *t, jl_unionall_t *u, jl_stenv_ { jl_value_t *res = NULL; jl_savedenv_t se; - jl_varbinding_t vb = { u->var, u->var->lb, u->var->ub, R, 0, 0, 0, 0, 0, 0, 0, 0, 0, + jl_varbinding_t vb = { u->var, u->var->lb, u->var->ub, R, 0, 0, 0, 0, 0, 0, 0, 0, e->invdepth, NULL, e->vars }; JL_GC_PUSH4(&res, &vb.lb, &vb.ub, &vb.innervars); save_env(e, &se, 1); @@ -3341,7 +3343,7 @@ static jl_value_t *intersect_unionall(jl_value_t *t, jl_unionall_t *u, jl_stenv_ vb.ub = vb.var->ub; } restore_env(e, &se, vb.constraintkind == 1 ? 1 : 0); - vb.occurs = vb.occurs_cov = vb.occurs_inv = 0; + vb.occurs_cov = vb.occurs_inv = 0; res = intersect_unionall_(t, u, e, R, param, &vb); } } @@ -4042,79 +4044,12 @@ static jl_value_t *intersect(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, int pa return jl_bottom_type; } -static int merge_env(jl_stenv_t *e, jl_savedenv_t *se, int count) +static int merge_env(jl_stenv_t *e, jl_savedenv_t *me, jl_savedenv_t *se, int count) { - if (count == 0) - alloc_env(e, se, 1); - jl_value_t **roots = NULL; - int nroots = 0; - if (se->gcframe.nroots == JL_GC_ENCODE_PUSHARGS(1)) { - jl_svec_t *sv = (jl_svec_t*)se->roots[0]; - assert(jl_is_svec(sv)); - roots = jl_svec_data(sv); - nroots = jl_svec_len(sv); - } - else { - roots = se->roots; - nroots = se->gcframe.nroots >> 2; - } - int m = 0, n = 0; - jl_varbinding_t *v = e->vars; - while (v != NULL) { - if (count == 0) { - // need to initialize this - se->buf[m] = 0; - se->buf[m+1] = 0; - se->buf[m+2] = 0; - se->buf[m+3] = v->max_offset; - } - jl_value_t *b1, *b2; - if (v->occurs) { - // only merge lb/ub if this var occurs. - b1 = roots[n]; - JL_GC_PROMISE_ROOTED(b1); // clang-sagc doesn't know this came from our GC frame - b2 = v->lb; - JL_GC_PROMISE_ROOTED(b2); // clang-sagc doesn't know the fields of this are stack GC roots - roots[n] = b1 ? simple_meet(b1, b2, 0) : b2; - b1 = roots[n+1]; - JL_GC_PROMISE_ROOTED(b1); // clang-sagc doesn't know this came from our GC frame - b2 = v->ub; - JL_GC_PROMISE_ROOTED(b2); // clang-sagc doesn't know the fields of this are stack GC roots - roots[n+1] = b1 ? simple_join(b1, b2) : b2; - // record the meeted vars. - se->buf[m] = 1; - } - // `innervars` might be re-sorted inside `finish_unionall`. - // We'd better always merge it. - b1 = roots[n+2]; - JL_GC_PROMISE_ROOTED(b1); // clang-sagc doesn't know this came from our GC frame - b2 = (jl_value_t*)v->innervars; - JL_GC_PROMISE_ROOTED(b2); // clang-sagc doesn't know the fields of this are stack GC roots - if (b2 && b1 != b2) { - if (b1) - jl_array_ptr_1d_append((jl_array_t*)b1, (jl_array_t*)b2); - else - roots[n+2] = b2; - } - // always merge occurs_inv/cov by max (never decrease) - if (v->occurs_inv > se->buf[m+1]) - se->buf[m+1] = v->occurs_inv; - if (v->occurs_cov > se->buf[m+2]) - se->buf[m+2] = v->occurs_cov; - // always merge max_offset by min - if (!v->intersected && v->max_offset < se->buf[m+3]) - se->buf[m+3] = v->max_offset; - m = m + 4; - n = n + 3; - v = v->prev; + if (count == 0) { + save_env(e, me, 1); + return 1; } - assert(n == nroots); (void)nroots; - return count + 1; -} - -// merge untouched vars' info. -static void final_merge_env(jl_stenv_t *e, jl_savedenv_t *me, jl_savedenv_t *se) -{ jl_value_t **merged = NULL; jl_value_t **saved = NULL; int nroots = 0; @@ -4136,47 +4071,49 @@ static void final_merge_env(jl_stenv_t *e, jl_savedenv_t *me, jl_savedenv_t *se) } assert(nroots == current_env_length(e) * 3); assert(nroots % 3 == 0); - for (int n = 0, m = 0; n < nroots; n += 3, m += 4) { - if (merged[n] == NULL) - merged[n] = saved[n]; - if (merged[n+1] == NULL) - merged[n+1] = saved[n+1]; - jl_value_t *b1, *b2; + int m = 0, n = 0; + jl_varbinding_t *v = e->vars; + while (v != NULL) { + jl_value_t *b0, *b1, *b2; + // merge `lb` + b0 = saved[n]; + b1 = merged[n]; + JL_GC_PROMISE_ROOTED(b1); // clang-sagc doesn't know this came from our GC frame + b2 = v->lb; + JL_GC_PROMISE_ROOTED(b2); // clang-sagc doesn't know the fields of this are stack GC roots + merged[n] = (b1 == b0 || b2 == b0) ? b0 : simple_meet(b1, b2, 0); + // merge `ub` + b0 = saved[n+1]; + b1 = merged[n+1]; + JL_GC_PROMISE_ROOTED(b1); // clang-sagc doesn't know this came from our GC frame + b2 = v->ub; + JL_GC_PROMISE_ROOTED(b2); // clang-sagc doesn't know the fields of this are stack GC roots + merged[n+1] = (b1 == b0 || b2 == b0) ? b0 : simple_join(b1, b2); + // merge `innervars` b1 = merged[n+2]; JL_GC_PROMISE_ROOTED(b1); // clang-sagc doesn't know this came from our GC frame - b2 = saved[n+2]; - JL_GC_PROMISE_ROOTED(b2); // clang-sagc doesn't know this came from our GC frame + b2 = (jl_value_t*)v->innervars; + JL_GC_PROMISE_ROOTED(b2); // clang-sagc doesn't know the fields of this are stack GC roots if (b2 && b1 != b2) { if (b1) jl_array_ptr_1d_append((jl_array_t*)b1, (jl_array_t*)b2); else merged[n+2] = b2; } - me->buf[m] |= se->buf[m]; - } -} - -static void expand_local_env(jl_stenv_t *e, jl_value_t *res) -{ - jl_varbinding_t *v = e->vars; - // Here we pull in some typevar missed in fastpath. - while (v != NULL) { - v->occurs = v->occurs || jl_has_typevar(res, v->var); - assert(v->occurs == 0 || v->occurs == 1); - v = v->prev; - } - v = e->vars; - while (v != NULL) { - if (v->occurs == 1) { - jl_varbinding_t *v2 = e->vars; - while (v2 != NULL) { - if (v2 != v && v2->occurs == 0) - v2->occurs = -(jl_has_typevar(v->lb, v2->var) || jl_has_typevar(v->ub, v2->var)); - v2 = v2->prev; - } - } + // merge occurs_inv/cov by max (never decrease) + if (v->occurs_inv > me->buf[m]) + me->buf[m] = v->occurs_inv; + if (v->occurs_cov > me->buf[m+1]) + me->buf[m+1] = v->occurs_cov; + // merge max_offset by min + if (!v->intersected && v->max_offset < me->buf[m+2]) + me->buf[m+2] = v->max_offset; + m = m + 3; + n = n + 3; v = v->prev; } + assert(n == nroots); (void)nroots; + return count + 1; } static jl_value_t *intersect_all(jl_value_t *x, jl_value_t *y, jl_stenv_t *e) @@ -4189,12 +4126,9 @@ static jl_value_t *intersect_all(jl_value_t *x, jl_value_t *y, jl_stenv_t *e) jl_savedenv_t se, me; save_env(e, &se, 1); int niter = 0, total_iter = 0; - clean_occurs(e); is[0] = intersect(x, y, e, 0); // root - if (is[0] != jl_bottom_type) { - expand_local_env(e, is[0]); - niter = merge_env(e, &me, niter); - } + if (is[0] != jl_bottom_type) + niter = merge_env(e, &me, &se, niter); restore_env(e, &se, 1); while (next_union_state(e, 1)) { if (e->emptiness_only && is[0] != jl_bottom_type) @@ -4202,12 +4136,9 @@ static jl_value_t *intersect_all(jl_value_t *x, jl_value_t *y, jl_stenv_t *e) e->Runions.depth = 0; e->Runions.more = 0; - clean_occurs(e); is[1] = intersect(x, y, e, 0); - if (is[1] != jl_bottom_type) { - expand_local_env(e, is[1]); - niter = merge_env(e, &me, niter); - } + if (is[1] != jl_bottom_type) + niter = merge_env(e, &me, &se, niter); restore_env(e, &se, 1); if (is[0] == jl_bottom_type) is[0] = is[1]; @@ -4216,13 +4147,18 @@ static jl_value_t *intersect_all(jl_value_t *x, jl_value_t *y, jl_stenv_t *e) is[0] = jl_type_union(is, 2); } total_iter++; - if (niter > 4 || total_iter > 400000) { + if (has_next_union_state(e, 1) && (niter > 4 || total_iter > 400000)) { is[0] = y; + // we give up precise intersection here, just restore the saved env + restore_env(e, &se, 1); + if (niter > 0) { + free_env(&me); + niter = 0; + } break; } } if (niter) { - final_merge_env(e, &me, &se); restore_env(e, &me, 1); free_env(&me); } @@ -4707,7 +4643,7 @@ static jl_value_t *_widen_diagonal(jl_value_t *t, jl_varbinding_t *troot) { static jl_value_t *widen_diagonal(jl_value_t *t, jl_unionall_t *u, jl_varbinding_t *troot) { - jl_varbinding_t vb = { u->var, NULL, NULL, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, troot }; + jl_varbinding_t vb = { u->var, NULL, NULL, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, troot }; jl_value_t *nt; JL_GC_PUSH2(&vb.innervars, &nt); if (jl_is_unionall(u->body)) @@ -4730,6 +4666,56 @@ JL_DLLEXPORT jl_value_t *jl_widen_diagonal(jl_value_t *t, jl_unionall_t *ua) } // specificity comparison +static int count_missing_wrap(jl_value_t *x, jl_typeenv_t *env) +{ + if (!jl_has_free_typevars(x)) + return 0; + jl_typeenv_t *wrapped = NULL; + int count = 0; + for (jl_typeenv_t *env2 = env; env2 != NULL; env2 = env2->prev) { + int need_wrap = 0; + for (jl_typeenv_t *env3 = wrapped; env3 != NULL && need_wrap == 0; env3 = env3->prev) { + if (env3->var == env2->var) + need_wrap = -1; + else if (jl_has_typevar(env3->var->lb, env2->var) || jl_has_typevar(env3->var->ub, env2->var)) + need_wrap = 1; + } + need_wrap = need_wrap == 0 ? jl_has_typevar(x, env2->var) : + need_wrap == -1 ? 0 : 1; + if (need_wrap) { + count++; + jl_typeenv_t *newenv = (jl_typeenv_t*)alloca(sizeof(jl_typeenv_t)); + newenv->var = env2->var; + newenv->val = NULL; + newenv->prev = wrapped; + wrapped = newenv; + } + } + return count; +} + +static int obvious_subtype_msp(jl_value_t *x, jl_value_t *y, jl_value_t *y0, int *subtype, int wrapx, int wrapy) +{ + if (wrapx != 0 || wrapy != 0) { + int wrap_count = wrapx - wrapy; + while (wrap_count > 0 && jl_is_unionall(y)) + { + y = ((jl_unionall_t*)y)->body; + wrap_count--; + } + while (wrap_count < 0 && jl_is_unionall(x)) + { + x = ((jl_unionall_t*)x)->body; + wrap_count++; + } + if (wrap_count > 0) { + if (obvious_subtype(jl_unwrap_unionall(x), y, y0, subtype) && !*subtype) + return 1; + return 0; + } + } + return obvious_subtype(x, y, y0, subtype); +} static int eq_msp(jl_value_t *a, jl_value_t *b, jl_value_t *a0, jl_value_t *b0, jl_typeenv_t *env) { @@ -4752,12 +4738,14 @@ static int eq_msp(jl_value_t *a, jl_value_t *b, jl_value_t *a0, jl_value_t *b0, a = b; b = temp; } + int wrapa = count_missing_wrap(a, env); + int wrapb = count_missing_wrap(b, env); // first check if a <: b has an obvious answer int subtype_ab = 2; if (b == (jl_value_t*)jl_any_type || a == jl_bottom_type) { subtype_ab = 1; } - else if (obvious_subtype(a, b, b0, &subtype_ab)) { + else if (obvious_subtype_msp(a, b, b0, &subtype_ab, wrapa, wrapb)) { #ifdef NDEBUG if (subtype_ab == 0) return 0; @@ -4771,7 +4759,7 @@ static int eq_msp(jl_value_t *a, jl_value_t *b, jl_value_t *a0, jl_value_t *b0, if (a == (jl_value_t*)jl_any_type || b == jl_bottom_type) { subtype_ba = 1; } - else if (obvious_subtype(b, a, a0, &subtype_ba)) { + else if (obvious_subtype_msp(b, a, a0, &subtype_ba, wrapb, wrapa)) { #ifdef NDEBUG if (subtype_ba == 0) return 0; @@ -4836,7 +4824,9 @@ static int sub_msp(jl_value_t *x, jl_value_t *y, jl_value_t *y0, jl_typeenv_t *e return 1; } int obvious_sub = 2; - if (obvious_subtype(x, y, y0, &obvious_sub)) { + int wrapx = count_missing_wrap(x, env); + int wrapy = count_missing_wrap(y, env); + if (obvious_subtype_msp(x, y, y0, &obvious_sub, wrapx, wrapy)) { #ifdef NDEBUG return obvious_sub; #endif diff --git a/src/symbol.c b/src/symbol.c index b488a0cc77065..ef2c11e0842e8 100644 --- a/src/symbol.c +++ b/src/symbol.c @@ -15,6 +15,7 @@ extern "C" { #endif +uv_mutex_t symtab_lock; static _Atomic(jl_sym_t*) symtab = NULL; #define MAX_SYM_LEN ((size_t)INTPTR_MAX - sizeof(jl_taggedvalue_t) - sizeof(jl_sym_t) - 1) @@ -35,7 +36,7 @@ static jl_sym_t *mk_symbol(const char *str, size_t len) JL_NOTSAFEPOINT { jl_sym_t *sym; size_t nb = symbol_nbytes(len); - jl_taggedvalue_t *tag = (jl_taggedvalue_t*)jl_gc_perm_alloc_nolock(nb, 0, sizeof(void*), 0); + jl_taggedvalue_t *tag = (jl_taggedvalue_t*)jl_gc_perm_alloc(nb, 0, sizeof(void*), 0); sym = (jl_sym_t*)jl_valueof(tag); // set to old marked so that we won't look at it in the GC or write barrier. jl_set_typetagof(sym, jl_symbol_tag, GC_OLD_MARKED); @@ -86,15 +87,15 @@ jl_sym_t *_jl_symbol(const char *str, size_t len) JL_NOTSAFEPOINT // (or throw) _Atomic(jl_sym_t*) *slot; jl_sym_t *node = symtab_lookup(&symtab, str, len, &slot); if (node == NULL) { - uv_mutex_lock(&gc_perm_lock); + uv_mutex_lock(&symtab_lock); // Someone might have updated it, check and look up again if (jl_atomic_load_relaxed(slot) != NULL && (node = symtab_lookup(slot, str, len, &slot))) { - uv_mutex_unlock(&gc_perm_lock); + uv_mutex_unlock(&symtab_lock); return node; } node = mk_symbol(str, len); jl_atomic_store_release(slot, node); - uv_mutex_unlock(&gc_perm_lock); + uv_mutex_unlock(&symtab_lock); } return node; } diff --git a/src/threading.c b/src/threading.c index 0c4e1ccf70eb0..8f37ee814056c 100644 --- a/src/threading.c +++ b/src/threading.c @@ -404,6 +404,12 @@ jl_ptls_t jl_init_threadtls(int16_t tid) jl_fence(); uv_mutex_unlock(&tls_lock); +#if !defined(_OS_WINDOWS_) && !defined(JL_DISABLE_LIBUNWIND) && !defined(LLVMLIBUNWIND) + // ensures libunwind TLS space for this thread is allocated eagerly + // to make unwinding async-signal-safe even when using thread local caches. + unw_ensure_tls(); +#endif + return ptls; } @@ -459,8 +465,6 @@ void jl_safepoint_resume_all_threads(jl_task_t *ct) void jl_task_frame_noreturn(jl_task_t *ct) JL_NOTSAFEPOINT; void scheduler_delete_thread(jl_ptls_t ptls) JL_NOTSAFEPOINT; -void jl_free_thread_gc_state(jl_ptls_t ptls); - static void jl_delete_thread(void *value) JL_NOTSAFEPOINT_ENTER { #ifndef _OS_WINDOWS_ diff --git a/stdlib/Dates/docs/src/index.md b/stdlib/Dates/docs/src/index.md index 545dbd90775df..38b4f7ae86d29 100644 --- a/stdlib/Dates/docs/src/index.md +++ b/stdlib/Dates/docs/src/index.md @@ -684,9 +684,9 @@ value in the days field is uncertain. See the [API reference](@ref stdlib-dates-api) for additional information on methods exported from the `Dates` module. -# [API reference](@id stdlib-dates-api) +## [API reference](@id stdlib-dates-api) -## Dates and Time Types +### Dates and Time Types ```@docs Dates.Period @@ -701,7 +701,7 @@ Dates.TimeZone Dates.UTC ``` -## Dates Functions +### Dates Functions ```@docs Dates.DateTime(::Int64, ::Int64, ::Int64, ::Int64, ::Int64, ::Int64, ::Int64) @@ -730,7 +730,7 @@ Dates.now(::Type{Dates.UTC}) Base.eps(::Union{Type{DateTime}, Type{Date}, Type{Time}, TimeType}) ``` -### Accessor Functions +#### Accessor Functions ```@docs Dates.year @@ -758,7 +758,7 @@ Dates.monthday Dates.yearmonthday ``` -### Query Functions +#### Query Functions ```@docs Dates.dayname @@ -777,7 +777,7 @@ Dates.quarterofyear Dates.dayofquarter ``` -### Adjuster Functions +#### Adjuster Functions ```@docs Base.trunc(::Dates.TimeType, ::Type{Dates.Period}) @@ -797,7 +797,7 @@ Dates.tonext(::Function, ::Dates.TimeType) Dates.toprev(::Function, ::Dates.TimeType) ``` -### Periods +#### Periods ```@docs Dates.Period(::Any) @@ -808,7 +808,7 @@ Dates.default Dates.periods ``` -### Rounding Functions +#### Rounding Functions `Date` and `DateTime` values can be rounded to a specified resolution (e.g., 1 month or 15 minutes) with `floor`, `ceil`, or `round`. @@ -837,7 +837,7 @@ Dates.date2epochdays Dates.datetime2epochms ``` -### Conversion Functions +#### Conversion Functions ```@docs Dates.today diff --git a/stdlib/Dates/src/types.jl b/stdlib/Dates/src/types.jl index e1f7f900bff51..1978864b92554 100644 --- a/stdlib/Dates/src/types.jl +++ b/stdlib/Dates/src/types.jl @@ -203,7 +203,7 @@ function totaldays(y, m, d) end # If the year is divisible by 4, except for every 100 years, except for every 400 years -isleapyear(y) = (y % 4 == 0) && ((y % 100 != 0) || (y % 400 == 0)) +isleapyear(y::Integer) = (y % 4 == 0) && ((y % 100 != 0) || (y % 400 == 0)) # Number of days in month const DAYSINMONTH = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31) diff --git a/stdlib/Dates/test/types.jl b/stdlib/Dates/test/types.jl index 35a793867dc5a..f5284b376ca4a 100644 --- a/stdlib/Dates/test/types.jl +++ b/stdlib/Dates/test/types.jl @@ -41,6 +41,7 @@ end @test Dates.isleapyear(-1) == false @test Dates.isleapyear(4) == true @test Dates.isleapyear(-4) == true + @test_throws MethodError Dates.isleapyear(Dates.Year(1992)) end # Create "test" check manually y = Dates.Year(1) diff --git a/stdlib/JuliaSyntaxHighlighting.version b/stdlib/JuliaSyntaxHighlighting.version index 705f16c785a39..280db66afe5f9 100644 --- a/stdlib/JuliaSyntaxHighlighting.version +++ b/stdlib/JuliaSyntaxHighlighting.version @@ -1,4 +1,4 @@ JULIASYNTAXHIGHLIGHTING_BRANCH = main -JULIASYNTAXHIGHLIGHTING_SHA1 = a463611e715c9ec546ac8463c38b6890d892e0c8 +JULIASYNTAXHIGHLIGHTING_SHA1 = b89dd99db56700c47434df6106b6c6afd1c9ed01 JULIASYNTAXHIGHLIGHTING_GIT_URL := https://github.com/julialang/JuliaSyntaxHighlighting.jl.git JULIASYNTAXHIGHLIGHTING_TAR_URL = https://api.github.com/repos/julialang/JuliaSyntaxHighlighting.jl/tarball/$1 diff --git a/stdlib/LLD_jll/Project.toml b/stdlib/LLD_jll/Project.toml index 4f5e3a6659745..6a6cc72aa3c62 100644 --- a/stdlib/LLD_jll/Project.toml +++ b/stdlib/LLD_jll/Project.toml @@ -1,6 +1,6 @@ name = "LLD_jll" uuid = "d55e3150-da41-5e91-b323-ecfd1eec6109" -version = "17.0.6+4" +version = "18.1.7+2" [deps] Zlib_jll = "83775a58-1f1d-513f-b197-d71354ab007a" @@ -10,7 +10,7 @@ Artifacts = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" [compat] julia = "1.11" -libLLVM_jll = "17.0.6" +libLLVM_jll = "18.1.7" [extras] Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" diff --git a/stdlib/LibUnwind_jll/Project.toml b/stdlib/LibUnwind_jll/Project.toml index eda312ec0735e..03ccfcd1449d8 100644 --- a/stdlib/LibUnwind_jll/Project.toml +++ b/stdlib/LibUnwind_jll/Project.toml @@ -1,6 +1,6 @@ name = "LibUnwind_jll" uuid = "745a5e78-f969-53e9-954f-d19f2f74f4e3" -version = "1.8.1+0" +version = "1.8.1+1" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" diff --git a/stdlib/LinearAlgebra/src/LinearAlgebra.jl b/stdlib/LinearAlgebra/src/LinearAlgebra.jl index bad0431755e98..be59516f086ab 100644 --- a/stdlib/LinearAlgebra/src/LinearAlgebra.jl +++ b/stdlib/LinearAlgebra/src/LinearAlgebra.jl @@ -655,10 +655,6 @@ _evview(S::SymTridiagonal) = @view S.ev[begin:begin + length(S.dv) - 2] _zeros(::Type{T}, b::AbstractVector, n::Integer) where {T} = zeros(T, max(length(b), n)) _zeros(::Type{T}, B::AbstractMatrix, n::Integer) where {T} = zeros(T, max(size(B, 1), n), size(B, 2)) -# convert to Vector, if necessary -_makevector(x::Vector) = x -_makevector(x::AbstractVector) = Vector(x) - # append a zero element / drop the last element _pushzero(A) = (B = similar(A, length(A)+1); @inbounds B[begin:end-1] .= A; @inbounds B[end] = zero(eltype(B)); B) _droplast!(A) = deleteat!(A, lastindex(A)) diff --git a/stdlib/LinearAlgebra/src/adjtrans.jl b/stdlib/LinearAlgebra/src/adjtrans.jl index daee587b82835..b722e49bb2c3d 100644 --- a/stdlib/LinearAlgebra/src/adjtrans.jl +++ b/stdlib/LinearAlgebra/src/adjtrans.jl @@ -302,6 +302,16 @@ function Base.showarg(io::IO, v::Transpose, toplevel) toplevel && print(io, " with eltype ", eltype(v)) return nothing end +function Base.show(io::IO, v::Adjoint{<:Real, <:AbstractVector}) + print(io, "adjoint(") + show(io, parent(v)) + print(io, ")") +end +function Base.show(io::IO, v::Transpose{<:Number, <:AbstractVector}) + print(io, "transpose(") + show(io, parent(v)) + print(io, ")") +end # some aliases for internal convenience use const AdjOrTrans{T,S} = Union{Adjoint{T,S},Transpose{T,S}} where {T,S} diff --git a/stdlib/LinearAlgebra/src/bidiag.jl b/stdlib/LinearAlgebra/src/bidiag.jl index ddfc6af60ef75..5aa4314c9ae51 100644 --- a/stdlib/LinearAlgebra/src/bidiag.jl +++ b/stdlib/LinearAlgebra/src/bidiag.jl @@ -130,14 +130,14 @@ function bidiagzero(A::Bidiagonal{<:AbstractMatrix}, i, j) end end +_offdiagind(uplo) = uplo == 'U' ? 1 : -1 + @inline function Base.isassigned(A::Bidiagonal, i::Int, j::Int) @boundscheck checkbounds(Bool, A, i, j) || return false if i == j return @inbounds isassigned(A.dv, i) - elseif A.uplo == 'U' && (i == j - 1) - return @inbounds isassigned(A.ev, i) - elseif A.uplo == 'L' && (i == j + 1) - return @inbounds isassigned(A.ev, j) + elseif i == j - _offdiagind(A.uplo) + return @inbounds isassigned(A.ev, A.uplo == 'U' ? i : j) else return true end @@ -147,10 +147,8 @@ end @boundscheck checkbounds(A, i, j) if i == j return @inbounds Base.isstored(A.dv, i) - elseif A.uplo == 'U' && (i == j - 1) - return @inbounds Base.isstored(A.ev, i) - elseif A.uplo == 'L' && (i == j + 1) - return @inbounds Base.isstored(A.ev, j) + elseif i == j - _offdiagind(A.uplo) + return @inbounds Base.isstored(A.ev, A.uplo == 'U' ? i : j) else return false end @@ -160,10 +158,8 @@ end @boundscheck checkbounds(A, i, j) if i == j return @inbounds A.dv[i] - elseif A.uplo == 'U' && (i == j - 1) - return @inbounds A.ev[i] - elseif A.uplo == 'L' && (i == j + 1) - return @inbounds A.ev[j] + elseif i == j - _offdiagind(A.uplo) + return @inbounds A.ev[A.uplo == 'U' ? i : j] else return bidiagzero(A, i, j) end @@ -173,9 +169,7 @@ end @boundscheck checkbounds(A, _cartinds(b)) if b.band == 0 return @inbounds A.dv[b.index] - elseif A.uplo == 'U' && b.band == 1 - return @inbounds A.ev[b.index] - elseif A.uplo == 'L' && b.band == -1 + elseif b.band == _offdiagind(A.uplo) return @inbounds A.ev[b.index] else return bidiagzero(A, Tuple(_cartinds(b))...) @@ -186,13 +180,11 @@ end @boundscheck checkbounds(A, i, j) if i == j @inbounds A.dv[i] = x - elseif A.uplo == 'U' && (i == j - 1) - @inbounds A.ev[i] = x - elseif A.uplo == 'L' && (i == j + 1) - @inbounds A.ev[j] = x + elseif i == j - _offdiagind(A.uplo) + @inbounds A.ev[A.uplo == 'U' ? i : j] = x elseif !iszero(x) throw(ArgumentError(LazyString(lazy"cannot set entry ($i, $j) off the ", - istriu(A) ? "upper" : "lower", " bidiagonal band to a nonzero value ", x))) + A.uplo == 'U' ? "upper" : "lower", " bidiagonal band to a nonzero value ", x))) end return x end @@ -202,11 +194,7 @@ Base._reverse(A::Bidiagonal, ::Colon) = Bidiagonal(reverse(A.dv), reverse(A.ev), ## structured matrix methods ## function Base.replace_in_print_matrix(A::Bidiagonal,i::Integer,j::Integer,s::AbstractString) - if A.uplo == 'U' - i==j || i==j-1 ? s : Base.replace_with_centered_mark(s) - else - i==j || i==j+1 ? s : Base.replace_with_centered_mark(s) - end + i==j || i==j-_offdiagind(A.uplo) ? s : Base.replace_with_centered_mark(s) end #Converting from Bidiagonal to dense Matrix @@ -215,7 +203,7 @@ function Matrix{T}(A::Bidiagonal) where T if haszero(T) # optimized path for types with zero(T) defined size(B,1) > 1 && fill!(B, zero(T)) copyto!(view(B, diagind(B)), A.dv) - copyto!(view(B, diagind(B, A.uplo == 'U' ? 1 : -1)), A.ev) + copyto!(view(B, diagind(B, _offdiagind(A.uplo))), A.ev) else copyto!(B, A) end @@ -252,8 +240,8 @@ tr(B::Bidiagonal) = sum(B.dv) function kron(A::Diagonal, B::Bidiagonal) # `_droplast!` is only guaranteed to work with `Vector` - kdv = _makevector(kron(diag(A), B.dv)) - kev = _droplast!(_makevector(kron(diag(A), _pushzero(B.ev)))) + kdv = convert(Vector, kron(diag(A), B.dv)) + kev = _droplast!(convert(Vector, kron(diag(A), _pushzero(B.ev)))) Bidiagonal(kdv, kev, B.uplo) end @@ -276,12 +264,13 @@ end #################### function show(io::IO, M::Bidiagonal) - # TODO: make this readable and one-line - summary(io, M) - print(io, ":\n diag:") - print_matrix(io, (M.dv)') - print(io, M.uplo == 'U' ? "\n super:" : "\n sub:") - print_matrix(io, (M.ev)') + print(io, "Bidiagonal(") + show(io, M.dv) + print(io, ", ") + show(io, M.ev) + print(io, ", ") + show(io, sym_uplo(M.uplo)) + print(io, ")") end size(M::Bidiagonal) = (n = length(M.dv); (n, n)) @@ -298,7 +287,7 @@ adjoint(B::Bidiagonal{<:Number, <:Base.ReshapedArray{<:Number,1,<:Adjoint}}) = transpose(B::Bidiagonal{<:Number}) = Bidiagonal(B.dv, B.ev, B.uplo == 'U' ? :L : :U) permutedims(B::Bidiagonal) = Bidiagonal(B.dv, B.ev, B.uplo == 'U' ? 'L' : 'U') function permutedims(B::Bidiagonal, perm) - Base.checkdims_perm(B, B, perm) + Base.checkdims_perm(axes(B), axes(B), perm) NTuple{2}(perm) == (2, 1) ? permutedims(B) : B end function Base.copy(aB::Adjoint{<:Any,<:Bidiagonal}) @@ -310,18 +299,22 @@ function Base.copy(tB::Transpose{<:Any,<:Bidiagonal}) return Bidiagonal(map(x -> copy.(transpose.(x)), (B.dv, B.ev))..., B.uplo == 'U' ? :L : :U) end +@noinline function throw_zeroband_error(A) + uplo = A.uplo + zeroband = uplo == 'U' ? "lower" : "upper" + throw(ArgumentError(LazyString("cannot set the ", + zeroband, " bidiagonal band to a nonzero value for uplo=:", uplo))) +end + # copyto! for matching axes function _copyto_banded!(A::Bidiagonal, B::Bidiagonal) A.dv .= B.dv if A.uplo == B.uplo A.ev .= B.ev elseif iszero(B.ev) # diagonal source - A.ev .= zero.(A.ev) + A.ev .= B.ev else - zeroband = istriu(A) ? "lower" : "upper" - uplo = A.uplo - throw(ArgumentError(LazyString("cannot set the ", - zeroband, " bidiagonal band to a nonzero value for uplo=:", uplo))) + throw_zeroband_error(A) end return A end @@ -472,7 +465,7 @@ const BiTri = Union{Bidiagonal,Tridiagonal} # B .= A * B function lmul!(A::Bidiagonal, B::AbstractVecOrMat) - _muldiag_size_check(A, B) + _muldiag_size_check(size(A), size(B)) (; dv, ev) = A if A.uplo == 'U' for k in axes(B,2) @@ -493,7 +486,7 @@ function lmul!(A::Bidiagonal, B::AbstractVecOrMat) end # B .= D * B function lmul!(D::Diagonal, B::Bidiagonal) - _muldiag_size_check(D, B) + _muldiag_size_check(size(D), size(B)) (; dv, ev) = B isL = B.uplo == 'L' dv[1] = D.diag[1] * dv[1] @@ -505,7 +498,7 @@ function lmul!(D::Diagonal, B::Bidiagonal) end # B .= B * A function rmul!(B::AbstractMatrix, A::Bidiagonal) - _muldiag_size_check(A, B) + _muldiag_size_check(size(A), size(B)) (; dv, ev) = A if A.uplo == 'U' for k in reverse(axes(dv,1)[2:end]) @@ -530,7 +523,7 @@ function rmul!(B::AbstractMatrix, A::Bidiagonal) end # B .= B * D function rmul!(B::Bidiagonal, D::Diagonal) - _muldiag_size_check(B, D) + _muldiag_size_check(size(B), size(D)) (; dv, ev) = B isU = B.uplo == 'U' dv[1] *= D.diag[1] @@ -558,7 +551,7 @@ _diag(A::SymTridiagonal, k) = k == 0 ? A.dv : A.ev function _diag(A::Bidiagonal, k) if k == 0 return A.dv - elseif (A.uplo == 'L' && k == -1) || (A.uplo == 'U' && k == 1) + elseif k == _offdiagind(A.uplo) return A.ev else return diag(A, k) @@ -631,7 +624,6 @@ function _mul!(C::AbstractMatrix, A::BiTriSym, B::Diagonal, _add::MulAddMul) check_A_mul_B!_sizes(size(C), size(A), size(B)) n = size(A,1) iszero(n) && return C - n <= 3 && return mul!(C, Array(A), Array(B), _add.alpha, _add.beta) _rmul_or_fill!(C, _add.beta) # see the same use above iszero(_add.alpha) && return C Al = _diag(A, -1) @@ -640,28 +632,99 @@ function _mul!(C::AbstractMatrix, A::BiTriSym, B::Diagonal, _add::MulAddMul) Bd = B.diag @inbounds begin # first row of C - C[1,1] += _add(A[1,1]*B[1,1]) - C[1,2] += _add(A[1,2]*B[2,2]) + for j in 1:min(2, n) + C[1,j] += _add(A[1,j]*B[j,j]) + end # second row of C - C[2,1] += _add(A[2,1]*B[1,1]) - C[2,2] += _add(A[2,2]*B[2,2]) - C[2,3] += _add(A[2,3]*B[3,3]) + if n > 1 + for j in 1:min(3, n) + C[2,j] += _add(A[2,j]*B[j,j]) + end + end for j in 3:n-2 C[j, j-1] += _add(Al[j-1]*Bd[j-1]) C[j, j ] += _add(Ad[j ]*Bd[j ]) C[j, j+1] += _add(Au[j ]*Bd[j+1]) end - # row before last of C - C[n-1,n-2] += _add(A[n-1,n-2]*B[n-2,n-2]) - C[n-1,n-1] += _add(A[n-1,n-1]*B[n-1,n-1]) - C[n-1,n ] += _add(A[n-1, n]*B[n ,n ]) + if n > 3 + # row before last of C + for j in n-2:n + C[n-1,j] += _add(A[n-1,j]*B[j,j]) + end + end # last row of C - C[n,n-1] += _add(A[n,n-1]*B[n-1,n-1]) - C[n,n ] += _add(A[n,n ]*B[n, n ]) + if n > 2 + for j in n-1:n + C[n,j] += _add(A[n,j]*B[j,j]) + end + end end # inbounds C end +function _mul!(C::AbstractMatrix, A::Bidiagonal, B::Diagonal, _add::MulAddMul) + require_one_based_indexing(C) + check_A_mul_B!_sizes(size(C), size(A), size(B)) + n = size(A,1) + iszero(n) && return C + _rmul_or_fill!(C, _add.beta) # see the same use above + iszero(_add.alpha) && return C + (; dv, ev) = A + Bd = B.diag + rowshift = A.uplo == 'U' ? -1 : 1 + evshift = Int(A.uplo == 'U') + @inbounds begin + # first row of C + C[1,1] += _add(dv[1]*Bd[1]) + if n > 1 + if A.uplo == 'L' + C[2,1] += _add(ev[1]*Bd[1]) + end + for col in 2:n-1 + C[col+rowshift, col] += _add(ev[col - evshift]*Bd[col]) + C[col, col] += _add(dv[col]*Bd[col]) + end + if A.uplo == 'U' + C[n-1,n] += _add(ev[n-1]*Bd[n]) + end + C[n, n] += _add(dv[n]*Bd[n]) + end + end # inbounds + C +end + +function _mul!(C::Bidiagonal, A::Bidiagonal, B::Diagonal, _add::MulAddMul) + check_A_mul_B!_sizes(size(C), size(A), size(B)) + n = size(A,1) + iszero(n) && return C + iszero(_add.alpha) && return _rmul_or_fill!(C, _add.beta) + Adv, Aev = A.dv, A.ev + Cdv, Cev = C.dv, C.ev + Bd = B.diag + shift = Int(A.uplo == 'U') + if C.uplo == A.uplo + @inbounds begin + _modify!(_add, Adv[1]*Bd[1], Cdv, 1) + for j in eachindex(IndexLinear(), Aev, Cev) + _modify!(_add, Aev[j]*Bd[j+shift], Cev, j) + _modify!(_add, Adv[j+1]*Bd[j+1], Cdv, j+1) + end + end # inbounds + else + @inbounds begin + _modify!(_add, Adv[1]*Bd[1], Cdv, 1) + for j in eachindex(IndexLinear(), Aev, Cev) + _modify!(_add, Adv[j+1]*Bd[j+1], Cdv, j+1) + # this branch will error unless the value is zero + _modify!(_add, Aev[j]*Bd[j+shift], C, (j+1-shift, j+shift)) + # zeros of the correct type + _modify!(_add, A[j+shift, j+1-shift]*Bd[j+1-shift], Cev, j) + end + end + end + C +end + function _mul!(C::AbstractVecOrMat, A::BiTriSym, B::AbstractVecOrMat, _add::MulAddMul) require_one_based_indexing(C, B) nA = size(A,1) @@ -792,6 +855,68 @@ function _dibimul!(C, A, B, _add) end # inbounds C end +function _dibimul!(C::AbstractMatrix, A::Diagonal, B::Bidiagonal, _add) + require_one_based_indexing(C) + check_A_mul_B!_sizes(size(C), size(A), size(B)) + n = size(A,1) + iszero(n) && return C + _rmul_or_fill!(C, _add.beta) # see the same use above + iszero(_add.alpha) && return C + Ad = A.diag + Bdv, Bev = B.dv, B.ev + rowshift = B.uplo == 'U' ? -1 : 1 + evshift = Int(B.uplo == 'U') + @inbounds begin + # first row of C + C[1,1] += _add(Ad[1]*Bdv[1]) + if n > 1 + if B.uplo == 'L' + C[2,1] += _add(Ad[2]*Bev[1]) + end + for col in 2:n-1 + evrow = col+rowshift + C[evrow, col] += _add(Ad[evrow]*Bev[col - evshift]) + C[col, col] += _add(Ad[col]*Bdv[col]) + end + if B.uplo == 'U' + C[n-1,n] += _add(Ad[n-1]*Bev[n-1]) + end + C[n, n] += _add(Ad[n]*Bdv[n]) + end + end # inbounds + C +end +function _dibimul!(C::Bidiagonal, A::Diagonal, B::Bidiagonal, _add) + check_A_mul_B!_sizes(size(C), size(A), size(B)) + n = size(A,1) + n == 0 && return C + iszero(_add.alpha) && return _rmul_or_fill!(C, _add.beta) + Ad = A.diag + Bdv, Bev = B.dv, B.ev + Cdv, Cev = C.dv, C.ev + shift = Int(B.uplo == 'L') + if C.uplo == B.uplo + @inbounds begin + _modify!(_add, Ad[1]*Bdv[1], Cdv, 1) + for j in eachindex(IndexLinear(), Bev, Cev) + _modify!(_add, Ad[j+shift]*Bev[j], Cev, j) + _modify!(_add, Ad[j+1]*Bdv[j+1], Cdv, j+1) + end + end # inbounds + else + @inbounds begin + _modify!(_add, Ad[1]*Bdv[1], Cdv, 1) + for j in eachindex(IndexLinear(), Bev, Cev) + _modify!(_add, Ad[j+1]*Bdv[j+1], Cdv, j+1) + # this branch will error unless the value is zero + _modify!(_add, Ad[j+shift]*Bev[j], C, (j+shift, j+1-shift)) + # zeros of the correct type + _modify!(_add, Ad[j+1-shift]*B[j+1-shift,j+shift], Cev, j) + end + end + end + C +end function *(A::UpperOrUnitUpperTriangular, B::Bidiagonal) TS = promote_op(matprod, eltype(A), eltype(B)) diff --git a/stdlib/LinearAlgebra/src/bunchkaufman.jl b/stdlib/LinearAlgebra/src/bunchkaufman.jl index 5a73c656abe33..a44f1a1c99094 100644 --- a/stdlib/LinearAlgebra/src/bunchkaufman.jl +++ b/stdlib/LinearAlgebra/src/bunchkaufman.jl @@ -127,6 +127,9 @@ function bunchkaufman!(A::StridedMatrix{<:BlasFloat}, rook::Bool = false; check: end end +bkcopy_oftype(A, S) = eigencopy_oftype(A, S) +bkcopy_oftype(A::Symmetric{<:Complex}, S) = Symmetric(copytrito!(similar(parent(A), S, size(A)), A.data, A.uplo), sym_uplo(A.uplo)) + """ bunchkaufman(A, rook::Bool=false; check = true) -> S::BunchKaufman @@ -206,7 +209,7 @@ julia> S.L*S.D*S.L' - A[S.p, S.p] ``` """ bunchkaufman(A::AbstractMatrix{T}, rook::Bool=false; check::Bool = true) where {T} = - bunchkaufman!(eigencopy_oftype(A, typeof(sqrt(oneunit(T)))), rook; check = check) + bunchkaufman!(bkcopy_oftype(A, typeof(sqrt(oneunit(T)))), rook; check = check) BunchKaufman{T}(B::BunchKaufman) where {T} = BunchKaufman(convert(Matrix{T}, B.LD), B.ipiv, B.uplo, B.symmetric, B.rook, B.info) @@ -1540,7 +1543,7 @@ function bunchkaufman(A::AbstractMatrix{TS}, rook::Bool = false; check::Bool = true ) where TS <: ClosedScalar{TR} where TR <: ClosedReal - return bunchkaufman!(eigencopy_oftype(A, TS), rook; check) + return bunchkaufman!(bkcopy_oftype(A, TS), rook; check) end function bunchkaufman(A::AbstractMatrix{TS}, @@ -1562,15 +1565,15 @@ function bunchkaufman(A::AbstractMatrix{TS}, # We promote input to BigInt to avoid overflow problems if TA == Nothing if TS <: Integer - M = Rational{BigInt}.(eigencopy_oftype(A, TS)) + M = Rational{BigInt}.(bkcopy_oftype(A, TS)) else - M = Complex{Rational{BigInt}}.(eigencopy_oftype(A, TS)) + M = Complex{Rational{BigInt}}.(bkcopy_oftype(A, TS)) end else if TS <: Integer - M = TA(Rational{BigInt}.(eigencopy_oftype(A, TS)), Symbol(A.uplo)) + M = TA(Rational{BigInt}.(bkcopy_oftype(A, TS)), Symbol(A.uplo)) else - M = TA(Complex{Rational{BigInt}}.(eigencopy_oftype(A, TS)), + M = TA(Complex{Rational{BigInt}}.(bkcopy_oftype(A, TS)), Symbol(A.uplo)) end end diff --git a/stdlib/LinearAlgebra/src/dense.jl b/stdlib/LinearAlgebra/src/dense.jl index c441e8e658ac8..94a075ffaf24d 100644 --- a/stdlib/LinearAlgebra/src/dense.jl +++ b/stdlib/LinearAlgebra/src/dense.jl @@ -565,9 +565,6 @@ function (^)(A::AbstractMatrix{T}, p::Real) where T isinteger(p) && return integerpow(A, p) # If possible, use diagonalization - if issymmetric(A) - return (Symmetric(A)^p) - end if ishermitian(A) return (Hermitian(A)^p) end diff --git a/stdlib/LinearAlgebra/src/diagonal.jl b/stdlib/LinearAlgebra/src/diagonal.jl index b3826a2aa7f82..77459f7cca520 100644 --- a/stdlib/LinearAlgebra/src/diagonal.jl +++ b/stdlib/LinearAlgebra/src/diagonal.jl @@ -213,6 +213,11 @@ end function Base.replace_in_print_matrix(A::Diagonal,i::Integer,j::Integer,s::AbstractString) i==j ? s : Base.replace_with_centered_mark(s) end +function Base.show(io::IO, A::Diagonal) + print(io, "Diagonal(") + show(io, A.diag) + print(io, ")") +end parent(D::Diagonal) = D.diag @@ -268,10 +273,10 @@ end (-)(Da::Diagonal, Db::Diagonal) = Diagonal(Da.diag - Db.diag) for f in (:+, :-) - @eval function $f(D::Diagonal, S::Symmetric) + @eval function $f(D::Diagonal{<:Number}, S::Symmetric) return Symmetric($f(D, S.data), sym_uplo(S.uplo)) end - @eval function $f(S::Symmetric, D::Diagonal) + @eval function $f(S::Symmetric, D::Diagonal{<:Number}) return Symmetric($f(S.data, D), sym_uplo(S.uplo)) end @eval function $f(D::Diagonal{<:Real}, H::Hermitian) @@ -293,42 +298,39 @@ Base.literal_pow(::typeof(^), D::Diagonal, valp::Val) = Diagonal(Base.literal_pow.(^, D.diag, valp)) # for speed Base.literal_pow(::typeof(^), D::Diagonal, ::Val{-1}) = inv(D) # for disambiguation -function _muldiag_size_check(A, B) - nA = size(A, 2) - mB = size(B, 1) - @noinline throw_dimerr(::AbstractMatrix, nA, mB) = throw(DimensionMismatch(lazy"second dimension of A, $nA, does not match first dimension of B, $mB")) - @noinline throw_dimerr(::AbstractVector, nA, mB) = throw(DimensionMismatch(lazy"second dimension of D, $nA, does not match length of V, $mB")) - nA == mB || throw_dimerr(B, nA, mB) +function _muldiag_size_check(szA::NTuple{2,Integer}, szB::Tuple{Integer,Vararg{Integer}}) + nA = szA[2] + mB = szB[1] + @noinline throw_dimerr(szB::NTuple{2}, nA, mB) = throw(DimensionMismatch(lazy"second dimension of A, $nA, does not match first dimension of B, $mB")) + @noinline throw_dimerr(szB::NTuple{1}, nA, mB) = throw(DimensionMismatch(lazy"second dimension of D, $nA, does not match length of V, $mB")) + nA == mB || throw_dimerr(szB, nA, mB) return nothing end # the output matrix should have the same size as the non-diagonal input matrix or vector @noinline throw_dimerr(szC, szA) = throw(DimensionMismatch(lazy"output matrix has size: $szC, but should have size $szA")) -_size_check_out(C, ::Diagonal, A) = _size_check_out(C, A) -_size_check_out(C, A, ::Diagonal) = _size_check_out(C, A) -_size_check_out(C, A::Diagonal, ::Diagonal) = _size_check_out(C, A) -function _size_check_out(C, A) - szA = size(A) - szC = size(C) - szA == szC || throw_dimerr(szC, szA) - return nothing +function _size_check_out(szC::NTuple{2}, szA::NTuple{2}, szB::NTuple{2}) + (szC[1] == szA[1] && szC[2] == szB[2]) || throw_dimerr(szC, (szA[1], szB[2])) +end +function _size_check_out(szC::NTuple{1}, szA::NTuple{2}, szB::NTuple{1}) + szC[1] == szA[1] || throw_dimerr(szC, (szA[1],)) end -function _muldiag_size_check(C, A, B) - _muldiag_size_check(A, B) - _size_check_out(C, A, B) +function _muldiag_size_check(szC::Tuple{Vararg{Integer}}, szA::Tuple{Vararg{Integer}}, szB::Tuple{Vararg{Integer}}) + _muldiag_size_check(szA, szB) + _size_check_out(szC, szA, szB) end function (*)(Da::Diagonal, Db::Diagonal) - _muldiag_size_check(Da, Db) + _muldiag_size_check(size(Da), size(Db)) return Diagonal(Da.diag .* Db.diag) end function (*)(D::Diagonal, V::AbstractVector) - _muldiag_size_check(D, V) + _muldiag_size_check(size(D), size(V)) return D.diag .* V end function rmul!(A::AbstractMatrix, D::Diagonal) - _muldiag_size_check(A, D) + _muldiag_size_check(size(A), size(D)) for I in CartesianIndices(A) row, col = Tuple(I) @inbounds A[row, col] *= D.diag[col] @@ -337,7 +339,7 @@ function rmul!(A::AbstractMatrix, D::Diagonal) end # T .= T * D function rmul!(T::Tridiagonal, D::Diagonal) - _muldiag_size_check(T, D) + _muldiag_size_check(size(T), size(D)) (; dl, d, du) = T d[1] *= D.diag[1] for i in axes(dl,1) @@ -349,7 +351,7 @@ function rmul!(T::Tridiagonal, D::Diagonal) end function lmul!(D::Diagonal, B::AbstractVecOrMat) - _muldiag_size_check(D, B) + _muldiag_size_check(size(D), size(B)) for I in CartesianIndices(B) row = I[1] @inbounds B[I] = D.diag[row] * B[I] @@ -360,7 +362,7 @@ end # in-place multiplication with a diagonal # T .= D * T function lmul!(D::Diagonal, T::Tridiagonal) - _muldiag_size_check(D, T) + _muldiag_size_check(size(D), size(T)) (; dl, d, du) = T d[1] = D.diag[1] * d[1] for i in axes(dl,1) @@ -452,7 +454,7 @@ function __muldiag!(out, D1::Diagonal, D2::Diagonal, _add::MulAddMul{ais1,bis0}) end function _mul_diag!(out, A, B, _add) - _muldiag_size_check(out, A, B) + _muldiag_size_check(size(out), size(A), size(B)) __muldiag!(out, A, B, _add) return out end @@ -469,14 +471,14 @@ _mul!(C::AbstractMatrix, Da::Diagonal, Db::Diagonal, _add) = _mul_diag!(C, Da, Db, _add) function (*)(Da::Diagonal, A::AbstractMatrix, Db::Diagonal) - _muldiag_size_check(Da, A) - _muldiag_size_check(A, Db) + _muldiag_size_check(size(Da), size(A)) + _muldiag_size_check(size(A), size(Db)) return broadcast(*, Da.diag, A, permutedims(Db.diag)) end function (*)(Da::Diagonal, Db::Diagonal, Dc::Diagonal) - _muldiag_size_check(Da, Db) - _muldiag_size_check(Db, Dc) + _muldiag_size_check(size(Da), size(Db)) + _muldiag_size_check(size(Db), size(Dc)) return Diagonal(Da.diag .* Db.diag .* Dc.diag) end @@ -684,9 +686,9 @@ function kron(A::Diagonal, B::SymTridiagonal) end function kron(A::Diagonal, B::Tridiagonal) # `_droplast!` is only guaranteed to work with `Vector` - kd = _makevector(kron(diag(A), B.d)) - kdl = _droplast!(_makevector(kron(diag(A), _pushzero(B.dl)))) - kdu = _droplast!(_makevector(kron(diag(A), _pushzero(B.du)))) + kd = convert(Vector, kron(diag(A), B.d)) + kdl = _droplast!(convert(Vector, kron(diag(A), _pushzero(B.dl)))) + kdu = _droplast!(convert(Vector, kron(diag(A), _pushzero(B.du)))) Tridiagonal(kdl, kd, kdu) end @@ -743,7 +745,7 @@ adjoint(D::Diagonal{<:Number}) = Diagonal(vec(adjoint(D.diag))) adjoint(D::Diagonal{<:Number,<:Base.ReshapedArray{<:Number,1,<:Adjoint}}) = Diagonal(adjoint(parent(D.diag))) adjoint(D::Diagonal) = Diagonal(adjoint.(D.diag)) permutedims(D::Diagonal) = D -permutedims(D::Diagonal, perm) = (Base.checkdims_perm(D, D, perm); D) +permutedims(D::Diagonal, perm) = (Base.checkdims_perm(axes(D), axes(D), perm); D) function diag(D::Diagonal{T}, k::Integer=0) where T # every branch call similar(..., ::Int) to make sure the diff --git a/stdlib/LinearAlgebra/src/lapack.jl b/stdlib/LinearAlgebra/src/lapack.jl index e9cfacfcd0cfd..97dff0031329b 100644 --- a/stdlib/LinearAlgebra/src/lapack.jl +++ b/stdlib/LinearAlgebra/src/lapack.jl @@ -5329,7 +5329,7 @@ for (syev, syevr, syevd, sygvd, elty) in # INTEGER INFO, LDA, LWORK, N # * .. Array Arguments .. # DOUBLE PRECISION A( LDA, * ), W( * ), WORK( * ) - function syev!(jobz::AbstractChar, uplo::AbstractChar, A::AbstractMatrix{$elty}) + Base.@constprop :aggressive function syev!(jobz::AbstractChar, uplo::AbstractChar, A::AbstractMatrix{$elty}) require_one_based_indexing(A) @chkvalidparam 1 jobz ('N', 'V') chkuplo(uplo) @@ -5429,7 +5429,7 @@ for (syev, syevr, syevd, sygvd, elty) in # * .. Array Arguments .. # INTEGER IWORK( * ) # DOUBLE PRECISION A( LDA, * ), W( * ), WORK( * ) - function syevd!(jobz::AbstractChar, uplo::AbstractChar, A::AbstractMatrix{$elty}) + Base.@constprop :aggressive function syevd!(jobz::AbstractChar, uplo::AbstractChar, A::AbstractMatrix{$elty}) require_one_based_indexing(A) @chkvalidparam 1 jobz ('N', 'V') chkstride1(A) @@ -5526,7 +5526,7 @@ for (syev, syevr, syevd, sygvd, elty, relty) in # * .. Array Arguments .. # DOUBLE PRECISION RWORK( * ), W( * ) # COMPLEX*16 A( LDA, * ), WORK( * ) - function syev!(jobz::AbstractChar, uplo::AbstractChar, A::AbstractMatrix{$elty}) + Base.@constprop :aggressive function syev!(jobz::AbstractChar, uplo::AbstractChar, A::AbstractMatrix{$elty}) require_one_based_indexing(A) @chkvalidparam 1 jobz ('N', 'V') chkstride1(A) @@ -5639,7 +5639,7 @@ for (syev, syevr, syevd, sygvd, elty, relty) in # INTEGER IWORK( * ) # DOUBLE PRECISION RWORK( * ) # COMPLEX*16 A( LDA, * ), WORK( * ) - function syevd!(jobz::AbstractChar, uplo::AbstractChar, A::AbstractMatrix{$elty}) + Base.@constprop :aggressive function syevd!(jobz::AbstractChar, uplo::AbstractChar, A::AbstractMatrix{$elty}) require_one_based_indexing(A) @chkvalidparam 1 jobz ('N', 'V') chkstride1(A) @@ -6452,7 +6452,7 @@ for (gees, gges, gges3, elty) in resize!(work, lwork) end end - A, vs, iszero(wi) ? wr : complex.(wr, wi) + iszero(wi) ? (A, vs, wr) : (A, vs, complex.(wr, wi)) end # * .. Scalar Arguments .. @@ -6833,7 +6833,7 @@ for (trexc, trsen, tgsen, elty) in resize!(iwork, liwork) end end - T, Q, iszero(wi) ? wr : complex.(wr, wi), s[], sep[] + iszero(wi) ? (T, Q, wr, s[], sep[]) : (T, Q, complex.(wr, wi), s[], sep[]) end trsen!(select::AbstractVector{BlasInt}, T::AbstractMatrix{$elty}, Q::AbstractMatrix{$elty}) = trsen!('N', 'V', select, T, Q) diff --git a/stdlib/LinearAlgebra/src/lbt.jl b/stdlib/LinearAlgebra/src/lbt.jl index 02b4411566290..606ddedbe1343 100644 --- a/stdlib/LinearAlgebra/src/lbt.jl +++ b/stdlib/LinearAlgebra/src/lbt.jl @@ -284,6 +284,25 @@ function lbt_find_backing_library(symbol_name, interface::Symbol; end +""" + lbt_forwarded_funcs(config::LBTConfig, lib::LBTLibraryInfo) + +Given a backing library `lib`, return the list of all functions that are +forwarded to that library, as a vector of `String`s. +""" +function lbt_forwarded_funcs(config::LBTConfig, lib::LBTLibraryInfo) + forwarded_funcs = String[] + for (symbol_idx, symbol) in enumerate(config.exported_symbols) + forward_byte_offset = div(symbol_idx - 1, 8) + forward_byte_mask = 1 << mod(symbol_idx - 1, 8) + if lib.active_forwards[forward_byte_offset+1] & forward_byte_mask != 0x00 + push!(forwarded_funcs, symbol) + end + end + return forwarded_funcs +end + + ## NOTE: Manually setting forwards is referred to as the 'footgun API'. It allows truly ## bizarre and complex setups to be created. If you run into strange errors while using ## it, the first thing you should ask yourself is whether you've set things up properly. diff --git a/stdlib/LinearAlgebra/src/qr.jl b/stdlib/LinearAlgebra/src/qr.jl index 0f81a07e12b08..9a89e58372d08 100644 --- a/stdlib/LinearAlgebra/src/qr.jl +++ b/stdlib/LinearAlgebra/src/qr.jl @@ -417,7 +417,7 @@ true `qr` returns multiple types because LAPACK uses several representations that minimize the memory storage requirements of products of Householder elementary reflectors, so that the `Q` and `R` matrices can be stored - compactly rather as two separate dense matrices. + compactly rather than two separate dense matrices. """ function qr(A::AbstractMatrix{T}, arg...; kwargs...) where T require_one_based_indexing(A) diff --git a/stdlib/LinearAlgebra/src/special.jl b/stdlib/LinearAlgebra/src/special.jl index 9633594574055..28a1b4b1b2eab 100644 --- a/stdlib/LinearAlgebra/src/special.jl +++ b/stdlib/LinearAlgebra/src/special.jl @@ -320,20 +320,20 @@ function copyto!(dest::BandedMatrix, src::BandedMatrix) end function _copyto_banded!(T::Tridiagonal, D::Diagonal) T.d .= D.diag - T.dl .= zero.(T.dl) - T.du .= zero.(T.du) + T.dl .= view(D, diagind(D, -1, IndexStyle(D))) + T.du .= view(D, diagind(D, 1, IndexStyle(D))) return T end function _copyto_banded!(SymT::SymTridiagonal, D::Diagonal) issymmetric(D) || throw(ArgumentError("cannot copy a non-symmetric Diagonal matrix to a SymTridiagonal")) SymT.dv .= D.diag _ev = _evview(SymT) - _ev .= zero.(_ev) + _ev .= view(D, diagind(D, 1, IndexStyle(D))) return SymT end function _copyto_banded!(B::Bidiagonal, D::Diagonal) B.dv .= D.diag - B.ev .= zero.(B.ev) + B.ev .= view(D, diagind(D, B.uplo == 'U' ? 1 : -1, IndexStyle(D))) return B end function _copyto_banded!(D::Diagonal, B::Bidiagonal) @@ -361,10 +361,10 @@ function _copyto_banded!(T::Tridiagonal, B::Bidiagonal) T.d .= B.dv if B.uplo == 'U' T.du .= B.ev - T.dl .= zero.(T.dl) + T.dl .= view(B, diagind(B, -1, IndexStyle(B))) else T.dl .= B.ev - T.du .= zero.(T.du) + T.du .= view(B, diagind(B, 1, IndexStyle(B))) end return T end @@ -372,7 +372,7 @@ function _copyto_banded!(SymT::SymTridiagonal, B::Bidiagonal) issymmetric(B) || throw(ArgumentError("cannot copy a non-symmetric Bidiagonal matrix to a SymTridiagonal")) SymT.dv .= B.dv _ev = _evview(SymT) - _ev .= zero.(_ev) + _ev .= B.ev return SymT end function _copyto_banded!(B::Bidiagonal, T::Tridiagonal) diff --git a/stdlib/LinearAlgebra/src/symmetric.jl b/stdlib/LinearAlgebra/src/symmetric.jl index f58670e255b58..d801158232673 100644 --- a/stdlib/LinearAlgebra/src/symmetric.jl +++ b/stdlib/LinearAlgebra/src/symmetric.jl @@ -821,7 +821,7 @@ function ^(A::Symmetric{<:Real}, p::Real) if all(λ -> λ ≥ 0, F.values) return Symmetric((F.vectors * Diagonal((F.values).^p)) * F.vectors') else - return Symmetric((F.vectors * Diagonal((complex(F.values)).^p)) * F.vectors') + return Symmetric((F.vectors * Diagonal(complex.(F.values).^p)) * F.vectors') end end function ^(A::Symmetric{<:Complex}, p::Real) @@ -853,7 +853,7 @@ function ^(A::Hermitian{T}, p::Real) where T return Hermitian(retmat) end else - return (F.vectors * Diagonal((complex(F.values).^p))) * F.vectors' + return (F.vectors * Diagonal((complex.(F.values).^p))) * F.vectors' end end @@ -983,7 +983,7 @@ for func in (:log, :sqrt) end return Hermitian(retmat) else - retmat = (F.vectors * Diagonal(($func).(complex(F.values)))) * F.vectors' + retmat = (F.vectors * Diagonal(($func).(complex.(F.values)))) * F.vectors' return retmat end end diff --git a/stdlib/LinearAlgebra/src/symmetriceigen.jl b/stdlib/LinearAlgebra/src/symmetriceigen.jl index 666b9a9bc81df..fee524a702187 100644 --- a/stdlib/LinearAlgebra/src/symmetriceigen.jl +++ b/stdlib/LinearAlgebra/src/symmetriceigen.jl @@ -4,6 +4,7 @@ # Call `copytrito!` instead of `copy_similar` to only copy the matching triangular half eigencopy_oftype(A::Hermitian, S) = Hermitian(copytrito!(similar(parent(A), S, size(A)), A.data, A.uplo), sym_uplo(A.uplo)) eigencopy_oftype(A::Symmetric, S) = Symmetric(copytrito!(similar(parent(A), S, size(A)), A.data, A.uplo), sym_uplo(A.uplo)) +eigencopy_oftype(A::Symmetric{<:Complex}, S) = copyto!(similar(parent(A), S), A) default_eigen_alg(A) = DivideAndConquer() diff --git a/stdlib/LinearAlgebra/src/triangular.jl b/stdlib/LinearAlgebra/src/triangular.jl index c45db3e90fab2..365ce8ee4bae2 100644 --- a/stdlib/LinearAlgebra/src/triangular.jl +++ b/stdlib/LinearAlgebra/src/triangular.jl @@ -702,6 +702,43 @@ function _triscale!(A::LowerOrUnitLowerTriangular, c::Number, B::UnitLowerTriang return A end +function _trirdiv!(A::UpperTriangular, B::UpperOrUnitUpperTriangular, c::Number) + n = checksize1(A, B) + for j in 1:n + for i in 1:j + @inbounds A[i, j] = B[i, j] / c + end + end + return A +end +function _trirdiv!(A::LowerTriangular, B::LowerOrUnitLowerTriangular, c::Number) + n = checksize1(A, B) + for j in 1:n + for i in j:n + @inbounds A[i, j] = B[i, j] / c + end + end + return A +end +function _trildiv!(A::UpperTriangular, c::Number, B::UpperOrUnitUpperTriangular) + n = checksize1(A, B) + for j in 1:n + for i in 1:j + @inbounds A[i, j] = c \ B[i, j] + end + end + return A +end +function _trildiv!(A::LowerTriangular, c::Number, B::LowerOrUnitLowerTriangular) + n = checksize1(A, B) + for j in 1:n + for i in j:n + @inbounds A[i, j] = c \ B[i, j] + end + end + return A +end + rmul!(A::UpperOrLowerTriangular, c::Number) = @inline _triscale!(A, A, c, MulAddMul()) lmul!(c::Number, A::UpperOrLowerTriangular) = @inline _triscale!(A, c, A, MulAddMul()) @@ -1095,7 +1132,11 @@ for (t, unitt) in ((UpperTriangular, UnitUpperTriangular), tstrided = t{<:Any, <:StridedMaybeAdjOrTransMat} @eval begin (*)(A::$t, x::Number) = $t(A.data*x) - (*)(A::$tstrided, x::Number) = A .* x + function (*)(A::$tstrided, x::Number) + eltype_dest = promote_op(*, eltype(A), typeof(x)) + dest = $t(similar(parent(A), eltype_dest)) + _triscale!(dest, x, A, MulAddMul()) + end function (*)(A::$unitt, x::Number) B = $t(A.data)*x @@ -1106,7 +1147,11 @@ for (t, unitt) in ((UpperTriangular, UnitUpperTriangular), end (*)(x::Number, A::$t) = $t(x*A.data) - (*)(x::Number, A::$tstrided) = x .* A + function (*)(x::Number, A::$tstrided) + eltype_dest = promote_op(*, typeof(x), eltype(A)) + dest = $t(similar(parent(A), eltype_dest)) + _triscale!(dest, x, A, MulAddMul()) + end function (*)(x::Number, A::$unitt) B = x*$t(A.data) @@ -1117,7 +1162,11 @@ for (t, unitt) in ((UpperTriangular, UnitUpperTriangular), end (/)(A::$t, x::Number) = $t(A.data/x) - (/)(A::$tstrided, x::Number) = A ./ x + function (/)(A::$tstrided, x::Number) + eltype_dest = promote_op(/, eltype(A), typeof(x)) + dest = $t(similar(parent(A), eltype_dest)) + _trirdiv!(dest, A, x) + end function (/)(A::$unitt, x::Number) B = $t(A.data)/x @@ -1129,7 +1178,11 @@ for (t, unitt) in ((UpperTriangular, UnitUpperTriangular), end (\)(x::Number, A::$t) = $t(x\A.data) - (\)(x::Number, A::$tstrided) = x .\ A + function (\)(x::Number, A::$tstrided) + eltype_dest = promote_op(\, typeof(x), eltype(A)) + dest = $t(similar(parent(A), eltype_dest)) + _trildiv!(dest, x, A) + end function (\)(x::Number, A::$unitt) B = x\$t(A.data) diff --git a/stdlib/LinearAlgebra/src/tridiag.jl b/stdlib/LinearAlgebra/src/tridiag.jl index 3198e45ad3eb8..0ba03634d82ad 100644 --- a/stdlib/LinearAlgebra/src/tridiag.jl +++ b/stdlib/LinearAlgebra/src/tridiag.jl @@ -173,7 +173,7 @@ adjoint(S::SymTridiagonal{<:Number, <:Base.ReshapedArray{<:Number,1,<:Adjoint}}) permutedims(S::SymTridiagonal) = S function permutedims(S::SymTridiagonal, perm) - Base.checkdims_perm(S, S, perm) + Base.checkdims_perm(axes(S), axes(S), perm) NTuple{2}(perm) == (2, 1) ? permutedims(S) : S end Base.copy(S::Adjoint{<:Any,<:SymTridiagonal}) = SymTridiagonal(map(x -> copy.(adjoint.(x)), (S.parent.dv, S.parent.ev))...) @@ -181,7 +181,7 @@ Base.copy(S::Adjoint{<:Any,<:SymTridiagonal}) = SymTridiagonal(map(x -> copy.(ad ishermitian(S::SymTridiagonal) = isreal(S.dv) && isreal(_evview(S)) issymmetric(S::SymTridiagonal) = true -tr(S::SymTridiagonal) = sum(S.dv) +tr(S::SymTridiagonal) = sum(symmetric, S.dv) @noinline function throw_diag_outofboundserror(n, sz) sz1, sz2 = sz @@ -639,7 +639,7 @@ adjoint(S::Tridiagonal{<:Number, <:Base.ReshapedArray{<:Number,1,<:Adjoint}}) = transpose(S::Tridiagonal{<:Number}) = Tridiagonal(S.du, S.d, S.dl) permutedims(T::Tridiagonal) = Tridiagonal(T.du, T.d, T.dl) function permutedims(T::Tridiagonal, perm) - Base.checkdims_perm(T, T, perm) + Base.checkdims_perm(axes(T), axes(T), perm) NTuple{2}(perm) == (2, 1) ? permutedims(T) : T end Base.copy(aS::Adjoint{<:Any,<:Tridiagonal}) = (S = aS.parent; Tridiagonal(map(x -> copy.(adjoint.(x)), (S.du, S.d, S.dl))...)) @@ -1040,8 +1040,26 @@ function _copyto_banded!(A::Tridiagonal, B::SymTridiagonal) return A end function _copyto_banded!(A::SymTridiagonal, B::Tridiagonal) - issymmetric(B) || throw(ArgumentError("cannot copy a non-symmetric Tridiagonal matrix to a SymTridiagonal")) + issymmetric(B) || throw(ArgumentError("cannot copy an asymmetric Tridiagonal matrix to a SymTridiagonal")) A.dv .= B.d _evview(A) .= B.du return A end + +# display +function show(io::IO, T::Tridiagonal) + print(io, "Tridiagonal(") + show(io, T.dl) + print(io, ", ") + show(io, T.d) + print(io, ", ") + show(io, T.du) + print(io, ")") +end +function show(io::IO, S::SymTridiagonal) + print(io, "SymTridiagonal(") + show(io, eltype(S) <: Number ? S.dv : view(S, diagind(S, IndexStyle(S)))) + print(io, ", ") + show(io, S.ev) + print(io, ")") +end diff --git a/stdlib/LinearAlgebra/test/adjtrans.jl b/stdlib/LinearAlgebra/test/adjtrans.jl index 1a66c7430723e..6cf2ff9ada09c 100644 --- a/stdlib/LinearAlgebra/test/adjtrans.jl +++ b/stdlib/LinearAlgebra/test/adjtrans.jl @@ -532,6 +532,11 @@ end @test String(take!(io)) == "transpose(::Matrix{Float64})" end +@testset "show" begin + @test repr(adjoint([1,2,3])) == "adjoint([1, 2, 3])" + @test repr(transpose([1f0,2f0])) == "transpose(Float32[1.0, 2.0])" +end + @testset "strided transposes" begin for t in (Adjoint, Transpose) @test strides(t(rand(3))) == (3, 1) diff --git a/stdlib/LinearAlgebra/test/bidiag.jl b/stdlib/LinearAlgebra/test/bidiag.jl index 2ff3e9b423702..e19d890237a26 100644 --- a/stdlib/LinearAlgebra/test/bidiag.jl +++ b/stdlib/LinearAlgebra/test/bidiag.jl @@ -143,11 +143,9 @@ Random.seed!(1) @testset "show" begin BD = Bidiagonal(dv, ev, :U) - dstring = sprint(Base.print_matrix,BD.dv') - estring = sprint(Base.print_matrix,BD.ev') - @test sprint(show,BD) == "$(summary(BD)):\n diag:$dstring\n super:$estring" + @test sprint(show,BD) == "Bidiagonal($(repr(dv)), $(repr(ev)), :U)" BD = Bidiagonal(dv,ev,:L) - @test sprint(show,BD) == "$(summary(BD)):\n diag:$dstring\n sub:$estring" + @test sprint(show,BD) == "Bidiagonal($(repr(dv)), $(repr(ev)), :L)" end @testset for uplo in (:U, :L) @@ -944,9 +942,6 @@ end @test_throws ArgumentError rmul!(B, A) @test_throws ArgumentError lmul!(A, B) end - D = Diagonal(dv) - @test rmul!(copy(A), D) ≈ A * D - @test lmul!(D, copy(A)) ≈ D * A end @testset "non-commutative" begin S32 = SizedArrays.SizedArray{(3,2)}(rand(3,2)) @@ -968,6 +963,42 @@ end end end +@testset "mul with Diagonal" begin + for n in 0:4 + dv, ev = rand(n), rand(max(n-1,0)) + d = rand(n) + for uplo in (:U, :L) + A = Bidiagonal(dv, ev, uplo) + D = Diagonal(d) + M = Matrix(A) + S = similar(A, size(A)) + @test A * D ≈ mul!(S, A, D) ≈ M * D + @test D * A ≈ mul!(S, D, A) ≈ D * M + @test mul!(copy(S), D, A, 2, 2) ≈ D * M * 2 + S * 2 + @test mul!(copy(S), A, D, 2, 2) ≈ M * D * 2 + S * 2 + + A2 = Bidiagonal(dv, zero(ev), uplo) + M2 = Array(A2) + S2 = Bidiagonal(copy(dv), copy(ev), uplo == (:U) ? (:L) : (:U)) + MS2 = Array(S2) + @test mul!(copy(S2), D, A2) ≈ D * M2 + @test mul!(copy(S2), A2, D) ≈ M2 * D + @test mul!(copy(S2), A2, D, 2, 2) ≈ M2 * D * 2 + MS2 * 2 + @test mul!(copy(S2), D, A2, 2, 2) ≈ D * M2 * 2 + MS2 * 2 + end + end + + t1 = SizedArrays.SizedArray{(2,3)}([1 2 3; 3 4 5]) + t2 = SizedArrays.SizedArray{(3,2)}([1 2; 3 4; 5 6]) + dv, ev, d = fill(t1, 4), fill(2t1, 3), fill(t2, 4) + for uplo in (:U, :L) + A = Bidiagonal(dv, ev, uplo) + D = Diagonal(d) + @test A * D ≈ Array(A) * Array(D) + @test D * A ≈ Array(D) * Array(A) + end +end + @testset "conversion to Tridiagonal for immutable bands" begin n = 4 dv = FillArrays.Fill(3, n) @@ -984,4 +1015,9 @@ end @test Tridiagonal{Float64}(B) === Tridiagonal(evf, dvf, zf) end +@testset "off-band indexing error" begin + B = Bidiagonal(Vector{BigInt}(undef, 4), Vector{BigInt}(undef,3), :L) + @test_throws "cannot set entry" B[1,2] = 4 +end + end # module TestBidiagonal diff --git a/stdlib/LinearAlgebra/test/diagonal.jl b/stdlib/LinearAlgebra/test/diagonal.jl index 1a3b8d4fd0ea7..29f3a38473d4a 100644 --- a/stdlib/LinearAlgebra/test/diagonal.jl +++ b/stdlib/LinearAlgebra/test/diagonal.jl @@ -1231,6 +1231,11 @@ Base.size(::SMatrix1) = (1, 1) @test C isa Matrix{SMatrix1{String}} end +@testset "show" begin + @test repr(Diagonal([1,2])) == "Diagonal([1, 2])" # 2-arg show + @test contains(repr(MIME"text/plain"(), Diagonal([1,2])), "⋅ 2") # 3-arg show +end + @testset "copyto! with UniformScaling" begin @testset "Fill" begin for len in (4, InfiniteArrays.Infinity()) @@ -1335,4 +1340,16 @@ end end end +@testset "+/- with block Symmetric/Hermitian" begin + for p in ([1 2; 3 4], [1 2+im; 2-im 4+2im]) + m = SizedArrays.SizedArray{(2,2)}(p) + D = Diagonal(fill(m, 2)) + for T in (Symmetric, Hermitian) + S = T(fill(m, 2, 2)) + @test D + S == Array(D) + Array(S) + @test S + D == Array(S) + Array(D) + end + end +end + end # module TestDiagonal diff --git a/stdlib/LinearAlgebra/test/hessenberg.jl b/stdlib/LinearAlgebra/test/hessenberg.jl index 767f40aa1e53f..54dbb70aa2065 100644 --- a/stdlib/LinearAlgebra/test/hessenberg.jl +++ b/stdlib/LinearAlgebra/test/hessenberg.jl @@ -272,4 +272,11 @@ end @test S[1,2] == S[Int8(1),UInt16(2)] == S[big(1), Int16(2)] end +@testset "complex Symmetric" begin + D = diagm(0=>ComplexF64[1,2]) + S = Symmetric(D) + H = hessenberg(S) + @test H.H == D +end + end # module TestHessenberg diff --git a/stdlib/LinearAlgebra/test/lapack.jl b/stdlib/LinearAlgebra/test/lapack.jl index fd14dad4634a8..f05d7d99c2437 100644 --- a/stdlib/LinearAlgebra/test/lapack.jl +++ b/stdlib/LinearAlgebra/test/lapack.jl @@ -889,4 +889,14 @@ end @test UpperTriangular(A) == UpperTriangular(B) end +@testset "inference in syev!/syevd!" begin + for T in (Float32, Float64), CT in (T, Complex{T}) + A = rand(CT, 4,4) + @inferred (A -> LAPACK.syev!('N', 'U', A))(A) + @inferred (A -> LAPACK.syev!('V', 'U', A))(A) + @inferred (A -> LAPACK.syevd!('N', 'U', A))(A) + @inferred (A -> LAPACK.syevd!('V', 'U', A))(A) + end +end + end # module TestLAPACK diff --git a/stdlib/LinearAlgebra/test/special.jl b/stdlib/LinearAlgebra/test/special.jl index 2f870373c9586..9bb84ba0e9d03 100644 --- a/stdlib/LinearAlgebra/test/special.jl +++ b/stdlib/LinearAlgebra/test/special.jl @@ -555,8 +555,8 @@ end @testset "from Diagonal" begin D = Diagonal(d) @testset "to Bidiagonal" begin - BU = Bidiagonal(zero(d), oneunit.(du), :U) - BL = Bidiagonal(zero(d), oneunit.(dl), :L) + BU = Bidiagonal(similar(d, BigInt), similar(du, BigInt), :U) + BL = Bidiagonal(similar(d, BigInt), similar(dl, BigInt), :L) for B in (BL, BU) copyto!(B, D) @test B == D @@ -573,7 +573,7 @@ end end end @testset "to Tridiagonal" begin - T = Tridiagonal(oneunit.(dl), zero(d), oneunit.(du)) + T = Tridiagonal(similar(dl, BigInt), similar(d, BigInt), similar(du, BigInt)) copyto!(T, D) @test T == D @@ -586,8 +586,8 @@ end end end @testset "to SymTridiagonal" begin - for du2 in (oneunit.(du), oneunit.(d)) - S = SymTridiagonal(zero(d), du2) + for du2 in (similar(du, BigInt), similar(d, BigInt)) + S = SymTridiagonal(similar(d), du2) copyto!(S, D) @test S == D end @@ -630,13 +630,14 @@ end end end @testset "to Tridiagonal" begin - T = Tridiagonal(oneunit.(dl), zero(d), oneunit.(du)) + T = Tridiagonal(similar(dl, BigInt), similar(d, BigInt), similar(du, BigInt)) for B in (BL, BU, BLones, BUones) copyto!(T, B) @test T == B end @testset "mismatched size" begin + T = Tridiagonal(oneunit.(dl), zero(d), oneunit.(du)) for uplo in (:L, :U) T .= 0 copyto!(T, Bidiagonal([1], Int[], uplo)) @@ -647,8 +648,8 @@ end end end @testset "to SymTridiagonal" begin - for du2 in (oneunit.(du), oneunit.(d)) - S = SymTridiagonal(zero(d), du2) + for du2 in (similar(du, BigInt), similar(d, BigInt)) + S = SymTridiagonal(similar(d, BigInt), du2) for B in (BL, BU) copyto!(S, B) @test S == B diff --git a/stdlib/LinearAlgebra/test/symmetriceigen.jl b/stdlib/LinearAlgebra/test/symmetriceigen.jl index cacdb72c63071..d55d1deb6bf33 100644 --- a/stdlib/LinearAlgebra/test/symmetriceigen.jl +++ b/stdlib/LinearAlgebra/test/symmetriceigen.jl @@ -173,4 +173,10 @@ end @test D.vectors ≈ D32.vectors end +@testset "complex Symmetric" begin + S = Symmetric(rand(ComplexF64,2,2)) + λ, v = eigen(S) + @test S * v ≈ v * Diagonal(λ) +end + end # module TestSymmetricEigen diff --git a/stdlib/LinearAlgebra/test/triangular.jl b/stdlib/LinearAlgebra/test/triangular.jl index 5ee8143e3f4bb..3f7cea91ec6d4 100644 --- a/stdlib/LinearAlgebra/test/triangular.jl +++ b/stdlib/LinearAlgebra/test/triangular.jl @@ -1180,4 +1180,18 @@ end @test V == Diagonal([1, 1]) end +@testset "preserve structure in scaling by NaN" begin + M = rand(Int8,2,2) + for (Ts, TD) in (((UpperTriangular, UnitUpperTriangular), UpperTriangular), + ((LowerTriangular, UnitLowerTriangular), LowerTriangular)) + for T in Ts + U = T(M) + for V in (U * NaN, NaN * U, U / NaN, NaN \ U) + @test V isa TD{Float64, Matrix{Float64}} + @test all(isnan, diag(V)) + end + end + end +end + end # module TestTriangular diff --git a/stdlib/LinearAlgebra/test/tridiag.jl b/stdlib/LinearAlgebra/test/tridiag.jl index fae708c4c8db4..e0a8e32d77852 100644 --- a/stdlib/LinearAlgebra/test/tridiag.jl +++ b/stdlib/LinearAlgebra/test/tridiag.jl @@ -18,6 +18,9 @@ using .Main.FillArrays isdefined(Main, :OffsetArrays) || @eval Main include(joinpath($(BASE_TEST_PATH), "testhelpers", "OffsetArrays.jl")) using .Main.OffsetArrays +isdefined(Main, :SizedArrays) || @eval Main include(joinpath($(BASE_TEST_PATH), "testhelpers", "SizedArrays.jl")) +using .Main.SizedArrays + include("testutils.jl") # test_approx_eq_modphase #Test equivalence of eigenvectors/singular vectors taking into account possible phase (sign) differences @@ -471,7 +474,7 @@ end end @testset "SymTridiagonal/Tridiagonal block matrix" begin - M = [1 2; 2 4] + M = [1 2; 3 4] n = 5 A = SymTridiagonal(fill(M, n), fill(M, n-1)) @test @inferred A[1,1] == Symmetric(M) @@ -485,6 +488,9 @@ end @test_throws ArgumentError diag(A, n+1) @test_throws ArgumentError diag(A, -n-1) + @test tr(A) == sum(diag(A)) + @test issymmetric(tr(A)) + A = Tridiagonal(fill(M, n-1), fill(M, n), fill(M, n-1)) @test @inferred A[1,1] == M @test @inferred A[1,2] == M @@ -805,7 +811,7 @@ end @test copyto!(zero(S), T) == T T2 = Tridiagonal(ones(length(ev)), zero(dv), zero(ev)) - @test_throws "cannot copy a non-symmetric Tridiagonal matrix to a SymTridiagonal" copyto!(zero(S), T2) + @test_throws "cannot copy an asymmetric Tridiagonal matrix to a SymTridiagonal" copyto!(zero(S), T2) @testset "mismatched sizes" begin dv2 = [4; @view dv[2:end]] @@ -911,4 +917,17 @@ end end end +@testset "show" begin + T = Tridiagonal(1:3, 1:4, 1:3) + @test sprint(show, T) == "Tridiagonal(1:3, 1:4, 1:3)" + S = SymTridiagonal(1:4, 1:3) + @test sprint(show, S) == "SymTridiagonal(1:4, 1:3)" + + m = SizedArrays.SizedArray{(2,2)}(reshape([1:4;],2,2)) + T = Tridiagonal(fill(m,2), fill(m,3), fill(m,2)) + @test sprint(show, T) == "Tridiagonal($(repr(diag(T,-1))), $(repr(diag(T))), $(repr(diag(T,1))))" + S = SymTridiagonal(fill(m,3), fill(m,2)) + @test sprint(show, S) == "SymTridiagonal($(repr(diag(S))), $(repr(diag(S,1))))" +end + end # module TestTridiagonal diff --git a/stdlib/OpenBLAS_jll/Project.toml b/stdlib/OpenBLAS_jll/Project.toml index 95dc40e6a0c2b..dfca282c74704 100644 --- a/stdlib/OpenBLAS_jll/Project.toml +++ b/stdlib/OpenBLAS_jll/Project.toml @@ -1,6 +1,6 @@ name = "OpenBLAS_jll" uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" -version = "0.3.27+1" +version = "0.3.28+0" [deps] # See note in `src/OpenBLAS_jll.jl` about this dependency. diff --git a/stdlib/Pkg.version b/stdlib/Pkg.version index 7742b41441528..964c43dfcc786 100644 --- a/stdlib/Pkg.version +++ b/stdlib/Pkg.version @@ -1,4 +1,4 @@ PKG_BRANCH = master -PKG_SHA1 = e4a6723bf3074764ff9266e5e13dfea501431b33 +PKG_SHA1 = 7aef1f044f3483e8b07d33fb4cfe918be554de69 PKG_GIT_URL := https://github.com/JuliaLang/Pkg.jl.git PKG_TAR_URL = https://api.github.com/repos/JuliaLang/Pkg.jl/tarball/$1 diff --git a/stdlib/Profile/src/Profile.jl b/stdlib/Profile/src/Profile.jl index 0a1f709a2ac60..55352cc4b3a9c 100644 --- a/stdlib/Profile/src/Profile.jl +++ b/stdlib/Profile/src/Profile.jl @@ -505,7 +505,7 @@ end # based on the package ecosystem function short_path(spath::Symbol, filenamecache::Dict{Symbol, String}) return get!(filenamecache, spath) do - path = string(spath) + path = Base.fixup_stdlib_path(string(spath)) if isabspath(path) if ispath(path) # try to replace the file-system prefix with a short "@Module" one, @@ -681,7 +681,7 @@ function add_fake_meta(data; threadid = 1, taskid = 0xf0f0f0f0) for i = 1:length(data) val = data[i] if iszero(val) - # (threadid, taskid, cpu_cycle_clock, thread_sleeping) + # META_OFFSET_THREADID, META_OFFSET_TASKID, META_OFFSET_CPUCYCLECLOCK, META_OFFSET_SLEEPSTATE push!(data_with_meta, threadid, taskid, cpu_clock_cycle+=1, false+1, 0, 0) else push!(data_with_meta, val) diff --git a/stdlib/Profile/src/heapsnapshot_reassemble.jl b/stdlib/Profile/src/heapsnapshot_reassemble.jl index 50da13e550d82..2413ae538b8ac 100644 --- a/stdlib/Profile/src/heapsnapshot_reassemble.jl +++ b/stdlib/Profile/src/heapsnapshot_reassemble.jl @@ -99,40 +99,42 @@ function assemble_snapshot(in_prefix, io::IO) orphans = Set{UInt}() # nodes that have no incoming edges # Parse nodes with empty edge counts that we need to fill later - nodes_file = open(string(in_prefix, ".nodes"), "r") - for i in 1:length(nodes) - node_type = read(nodes_file, Int8) - node_name_idx = read(nodes_file, UInt) - id = read(nodes_file, UInt) - self_size = read(nodes_file, Int) - @assert read(nodes_file, Int) == 0 # trace_node_id - @assert read(nodes_file, Int8) == 0 # detachedness - - nodes.type[i] = node_type - nodes.name_idx[i] = node_name_idx - nodes.id[i] = id - nodes.self_size[i] = self_size - nodes.edge_count[i] = 0 # edge_count - # populate the orphans set with node index - push!(orphans, i-1) + open(string(in_prefix, ".nodes"), "r") do nodes_file + for i in 1:length(nodes) + node_type = read(nodes_file, Int8) + node_name_idx = read(nodes_file, UInt) + id = read(nodes_file, UInt) + self_size = read(nodes_file, Int) + @assert read(nodes_file, Int) == 0 # trace_node_id + @assert read(nodes_file, Int8) == 0 # detachedness + + nodes.type[i] = node_type + nodes.name_idx[i] = node_name_idx + nodes.id[i] = id + nodes.self_size[i] = self_size + nodes.edge_count[i] = 0 # edge_count + # populate the orphans set with node index + push!(orphans, i-1) + end end # Parse the edges to fill in the edge counts for nodes and correct the to_node offsets - edges_file = open(string(in_prefix, ".edges"), "r") - for i in 1:length(nodes.edges) - edge_type = read(edges_file, Int8) - edge_name_or_index = read(edges_file, UInt) - from_node = read(edges_file, UInt) - to_node = read(edges_file, UInt) - - nodes.edges.type[i] = edge_type - nodes.edges.name_or_index[i] = edge_name_or_index - nodes.edges.to_pos[i] = to_node * k_node_number_of_fields # 7 fields per node, the streaming format doesn't multiply the offset by 7 - nodes.edge_count[from_node + 1] += UInt32(1) # C and JSON use 0-based indexing - push!(nodes.edge_idxs[from_node + 1], i) # Index into nodes.edges - # remove the node from the orphans if it has at least one incoming edge - if to_node in orphans - delete!(orphans, to_node) + open(string(in_prefix, ".edges"), "r") do edges_file + for i in 1:length(nodes.edges) + edge_type = read(edges_file, Int8) + edge_name_or_index = read(edges_file, UInt) + from_node = read(edges_file, UInt) + to_node = read(edges_file, UInt) + + nodes.edges.type[i] = edge_type + nodes.edges.name_or_index[i] = edge_name_or_index + nodes.edges.to_pos[i] = to_node * k_node_number_of_fields # 7 fields per node, the streaming format doesn't multiply the offset by 7 + nodes.edge_count[from_node + 1] += UInt32(1) # C and JSON use 0-based indexing + push!(nodes.edge_idxs[from_node + 1], i) # Index into nodes.edges + # remove the node from the orphans if it has at least one incoming edge + if to_node in orphans + delete!(orphans, to_node) + end end end diff --git a/stdlib/REPL/src/LineEdit.jl b/stdlib/REPL/src/LineEdit.jl index 1f6a782a23397..5af03e0df9b6d 100644 --- a/stdlib/REPL/src/LineEdit.jl +++ b/stdlib/REPL/src/LineEdit.jl @@ -66,6 +66,7 @@ show(io::IO, x::Prompt) = show(io, string("Prompt(\"", prompt_string(x.prompt), mutable struct MIState interface::ModalInterface active_module::Module + previous_active_module::Module current_mode::TextInterface aborted::Bool mode_state::IdDict{TextInterface,ModeState} @@ -78,7 +79,7 @@ mutable struct MIState async_channel::Channel{Function} end -MIState(i, mod, c, a, m) = MIState(i, mod, c, a, m, String[], 0, Char[], 0, :none, :none, Channel{Function}()) +MIState(i, mod, c, a, m) = MIState(i, mod, mod, c, a, m, String[], 0, Char[], 0, :none, :none, Channel{Function}()) const BufferLike = Union{MIState,ModeState,IOBuffer} const State = Union{MIState,ModeState} @@ -1510,13 +1511,11 @@ end current_word_with_dots(s::MIState) = current_word_with_dots(buffer(s)) -previous_active_module::Module = Main - function activate_module(s::MIState) word = current_word_with_dots(s); empty = isempty(word) mod = if empty - previous_active_module + s.previous_active_module else try Base.Core.eval(Base.active_module(), Base.Meta.parse(word)) @@ -1532,7 +1531,7 @@ function activate_module(s::MIState) if Base.active_module() == Main || mod == Main # At least one needs to be Main. Disallows toggling between two non-Main modules because it's # otherwise hard to get back to Main - global previous_active_module = Base.active_module() + s.previous_active_module = Base.active_module() end REPL.activate(mod) edit_clear(s) diff --git a/stdlib/REPL/src/REPL.jl b/stdlib/REPL/src/REPL.jl index 558f6ed9cab6f..67f5860082c8a 100644 --- a/stdlib/REPL/src/REPL.jl +++ b/stdlib/REPL/src/REPL.jl @@ -110,6 +110,8 @@ export LineEditREPL, StreamREPL +public TerminalMenus + import Base: AbstractDisplay, display, diff --git a/stdlib/REPL/src/REPLCompletions.jl b/stdlib/REPL/src/REPLCompletions.jl index bc8006ec2ed5d..dc21cfe529e46 100644 --- a/stdlib/REPL/src/REPLCompletions.jl +++ b/stdlib/REPL/src/REPLCompletions.jl @@ -556,8 +556,7 @@ struct REPLInterpreter <: CC.AbstractInterpreter function REPLInterpreter(limit_aggressive_inference::Bool=false; world::UInt = Base.get_world_counter(), inf_params::CC.InferenceParams = CC.InferenceParams(; - aggressive_constant_propagation=true, - unoptimize_throw_blocks=false), + aggressive_constant_propagation=true), opt_params::CC.OptimizationParams = CC.OptimizationParams(), inf_cache::Vector{CC.InferenceResult} = CC.InferenceResult[]) return new(limit_aggressive_inference, world, inf_params, opt_params, inf_cache) @@ -900,8 +899,11 @@ const superscript_regex = Regex("^\\\\\\^[" * join(isdigit(k) || isletter(k) ? " # Aux function to detect whether we're right after a using or import keyword function get_import_mode(s::String) + # allow all of these to start with leading whitespace and macros like @eval and @eval( + # ^\s*(?:@\w+\s*(?:\(\s*)?)? + # match simple cases like `using |` and `import |` - mod_import_match_simple = match(r"^\b(using|import)\s*$", s) + mod_import_match_simple = match(r"^\s*(?:@\w+\s*(?:\(\s*)?)?\b(using|import)\s*$", s) if mod_import_match_simple !== nothing if mod_import_match_simple[1] == "using" return :using_module @@ -910,7 +912,7 @@ function get_import_mode(s::String) end end # match module import statements like `using Foo|`, `import Foo, Bar|` and `using Foo.Bar, Baz, |` - mod_import_match = match(r"^\b(using|import)\s+([\w\.]+(?:\s*,\s*[\w\.]+)*),?\s*$", s) + mod_import_match = match(r"^\s*(?:@\w+\s*(?:\(\s*)?)?\b(using|import)\s+([\w\.]+(?:\s*,\s*[\w\.]+)*),?\s*$", s) if mod_import_match !== nothing if mod_import_match.captures[1] == "using" return :using_module @@ -919,7 +921,7 @@ function get_import_mode(s::String) end end # now match explicit name import statements like `using Foo: |` and `import Foo: bar, baz|` - name_import_match = match(r"^\b(using|import)\s+([\w\.]+)\s*:\s*([\w@!\s,]+)$", s) + name_import_match = match(r"^\s*(?:@\w+\s*(?:\(\s*)?)?\b(using|import)\s+([\w\.]+)\s*:\s*([\w@!\s,]+)$", s) if name_import_match !== nothing if name_import_match[1] == "using" return :using_name diff --git a/stdlib/REPL/src/TerminalMenus/TerminalMenus.jl b/stdlib/REPL/src/TerminalMenus/TerminalMenus.jl index ffbe32575fea1..f970cd9a289c2 100644 --- a/stdlib/REPL/src/TerminalMenus/TerminalMenus.jl +++ b/stdlib/REPL/src/TerminalMenus/TerminalMenus.jl @@ -1,5 +1,12 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +""" + REPL.TerminalMenus + +A module that contains code for displaying text mode interactive menus. +Key exported symbols include [`REPL.TerminalMenus.RadioMenu`](@ref) and +[`REPL.TerminalMenus.MultiSelectMenu`](@ref). +""" module TerminalMenus using ..REPL: REPL @@ -23,6 +30,9 @@ export Pager, request +public Config, config, MultiSelectConfig +public pick, cancel, writeline, options, numoptions, selected, header, keypress + # TODO: remove in Julia 2.0 # While not exported, AbstractMenu documented these as an extension interface @deprecate printMenu printmenu diff --git a/stdlib/REPL/test/precompilation.jl b/stdlib/REPL/test/precompilation.jl index 228cbd212a2c1..7efcf0b5e8282 100644 --- a/stdlib/REPL/test/precompilation.jl +++ b/stdlib/REPL/test/precompilation.jl @@ -15,8 +15,11 @@ if !Sys.iswindows() @testset "No interactive startup compilation" begin f, _ = mktemp() - # start an interactive session - cmd = `$(Base.julia_cmd()[1]) --trace-compile=$f -q --startup-file=no -i` + # start an interactive session, ensuring `TERM` is unset since it can trigger + # different amounts of precompilation stemming from `base/terminfo.jl` depending + # on the value, making the test here unreliable + cmd = addenv(`$(Base.julia_cmd()[1]) --trace-compile=$f -q --startup-file=no -i`, + Dict("TERM" => "")) pts, ptm = open_fake_pty() p = run(cmd, pts, pts, pts; wait=false) Base.close_stdio(pts) diff --git a/stdlib/REPL/test/repl.jl b/stdlib/REPL/test/repl.jl index 05db88fa0d8ac..f4d594b2a02e1 100644 --- a/stdlib/REPL/test/repl.jl +++ b/stdlib/REPL/test/repl.jl @@ -244,8 +244,9 @@ fake_repl(options = REPL.Options(confirm_exit=false,hascolor=true)) do stdin_wri @test occursin("shell> ", s) # check for the echo of the prompt @test occursin("'", s) # check for the echo of the input s = readuntil(stdout_read, "\n\n") - @test startswith(s, "\e[0mERROR: unterminated single quote\nStacktrace:\n [1] ") || - startswith(s, "\e[0m\e[1m\e[91mERROR: \e[39m\e[22m\e[91munterminated single quote\e[39m\nStacktrace:\n [1] ") + @test(startswith(s, "\e[0mERROR: unterminated single quote\nStacktrace:\n [1] ") || + startswith(s, "\e[0m\e[1m\e[91mERROR: \e[39m\e[22m\e[91munterminated single quote\e[39m\nStacktrace:\n [1] "), + skip = Sys.iswindows() && Sys.WORD_SIZE == 32) write(stdin_write, "\b") wait(t) end @@ -1216,9 +1217,9 @@ global some_undef_global @test occursin("does not exist", sprint(show, help_result(".."))) # test that helpmode is sensitive to contextual module @test occursin("No documentation found", sprint(show, help_result("Fix2", Main))) -@test occursin("A type representing a partially-applied version", # exact string may change +@test occursin("Alias for `Fix{2}`. See [`Fix`](@ref Base.Fix).", # exact string may change sprint(show, help_result("Base.Fix2", Main))) -@test occursin("A type representing a partially-applied version", # exact string may change +@test occursin("Alias for `Fix{2}`. See [`Fix`](@ref Base.Fix).", # exact string may change sprint(show, help_result("Fix2", Base))) @@ -1650,12 +1651,12 @@ fake_repl() do stdin_write, stdout_read, repl write(stdin_write, "foobar\n") readline(stdout_read) @test readline(stdout_read) == "\e[0mERROR: UndefVarError: `foobar` not defined in `Main`" - @test readline(stdout_read) == "" + @test readline(stdout_read) == "" skip = Sys.iswindows() && Sys.WORD_SIZE == 32 readuntil(stdout_read, "julia> ", keep=true) # check that top-level error did not change `err` write(stdin_write, "err\n") readline(stdout_read) - @test readline(stdout_read) == "\e[0m" + @test readline(stdout_read) == "\e[0m" skip = Sys.iswindows() && Sys.WORD_SIZE == 32 readuntil(stdout_read, "julia> ", keep=true) # generate deeper error write(stdin_write, "foo() = foobar\n") diff --git a/stdlib/REPL/test/replcompletions.jl b/stdlib/REPL/test/replcompletions.jl index 15e3de2668ba1..3f8addcace73b 100644 --- a/stdlib/REPL/test/replcompletions.jl +++ b/stdlib/REPL/test/replcompletions.jl @@ -2238,6 +2238,26 @@ let s = "using .Iss" @test res @test "Issue52922" in c end +let s = " using .Iss" + c, r, res = test_complete_context(s) + @test res + @test "Issue52922" in c +end +let s = "@time using .Iss" + c, r, res = test_complete_context(s) + @test res + @test "Issue52922" in c +end +let s = " @time using .Iss" + c, r, res = test_complete_context(s) + @test res + @test "Issue52922" in c +end +let s = "@time(using .Iss" + c, r, res = test_complete_context(s) + @test res + @test "Issue52922" in c +end let s = "using .Issue52922.Inn" c, r, res = test_complete_context(s) @test res diff --git a/stdlib/Random/src/Random.jl b/stdlib/Random/src/Random.jl index 9ce0896d0d125..26116d3bf4c81 100644 --- a/stdlib/Random/src/Random.jl +++ b/stdlib/Random/src/Random.jl @@ -29,6 +29,8 @@ export rand!, randn!, randcycle, randcycle!, AbstractRNG, MersenneTwister, RandomDevice, TaskLocalRNG, Xoshiro +public seed!, default_rng, Sampler, SamplerType, SamplerTrivial, SamplerSimple + ## general definitions """ diff --git a/stdlib/SparseArrays.version b/stdlib/SparseArrays.version index 7c99b8ba52d7c..019306a3e9f65 100644 --- a/stdlib/SparseArrays.version +++ b/stdlib/SparseArrays.version @@ -1,4 +1,4 @@ SPARSEARRAYS_BRANCH = main -SPARSEARRAYS_SHA1 = e61663ad0a79a48906b0b12d53506e731a614ab8 +SPARSEARRAYS_SHA1 = 0dd8d45d55b305458d0d3d3451057589b684f72f SPARSEARRAYS_GIT_URL := https://github.com/JuliaSparse/SparseArrays.jl.git SPARSEARRAYS_TAR_URL = https://api.github.com/repos/JuliaSparse/SparseArrays.jl/tarball/$1 diff --git a/stdlib/StyledStrings.version b/stdlib/StyledStrings.version index 2067083aec74b..83fbece4c8bc0 100644 --- a/stdlib/StyledStrings.version +++ b/stdlib/StyledStrings.version @@ -1,4 +1,4 @@ STYLEDSTRINGS_BRANCH = main -STYLEDSTRINGS_SHA1 = d7496d24d3f05536bce6a7eb4cd8ca05a75c02aa +STYLEDSTRINGS_SHA1 = f6035eb97b516862b16e36cab2ecc6ea8adc3d7c STYLEDSTRINGS_GIT_URL := https://github.com/JuliaLang/StyledStrings.jl.git STYLEDSTRINGS_TAR_URL = https://api.github.com/repos/JuliaLang/StyledStrings.jl/tarball/$1 diff --git a/stdlib/SuiteSparse_jll/Project.toml b/stdlib/SuiteSparse_jll/Project.toml index 314208ffc344c..39b8447138a2d 100644 --- a/stdlib/SuiteSparse_jll/Project.toml +++ b/stdlib/SuiteSparse_jll/Project.toml @@ -1,6 +1,6 @@ name = "SuiteSparse_jll" uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" -version = "7.7.0+0" +version = "7.8.0+0" [deps] libblastrampoline_jll = "8e850b90-86db-534c-a0d3-1478176c7d93" @@ -8,7 +8,7 @@ Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" Artifacts = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" [compat] -julia = "1.11" +julia = "1.12" [extras] Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" diff --git a/stdlib/Test/src/Test.jl b/stdlib/Test/src/Test.jl index 3ecf0c151164d..b4ada2ce3a9cf 100644 --- a/stdlib/Test/src/Test.jl +++ b/stdlib/Test/src/Test.jl @@ -1838,9 +1838,19 @@ function parse_testset_args(args) # a standalone symbol is assumed to be the test set we should use # the same is true for a symbol that's not exported from a module if isa(arg, Symbol) || Base.isexpr(arg, :.) + if testsettype !== nothing + msg = """Multiple testset types provided to @testset. \ + This is deprecated and may error in the future.""" + Base.depwarn(msg, :testset_multiple_testset_types; force=true) + end testsettype = esc(arg) # a string is the description elseif isa(arg, AbstractString) || (isa(arg, Expr) && arg.head === :string) + if desc !== nothing + msg = """Multiple descriptions provided to @testset. \ + This is deprecated and may error in the future.""" + Base.depwarn(msg, :testset_multiple_descriptions; force=true) + end desc = esc(arg) # an assignment is an option elseif isa(arg, Expr) && arg.head === :(=) diff --git a/stdlib/Test/test/runtests.jl b/stdlib/Test/test/runtests.jl index 31919c2881f6b..3ddcd7d5de0fd 100644 --- a/stdlib/Test/test/runtests.jl +++ b/stdlib/Test/test/runtests.jl @@ -1725,4 +1725,14 @@ end result = read(pipeline(ignorestatus(cmd), stderr=devnull), String) @test occursin(expected, result) end + +end + +@testset "Deprecated multiple arguments" begin + msg1 = """Multiple descriptions provided to @testset. \ + This is deprecated and may error in the future.""" + @test_deprecated msg1 @macroexpand @testset "name1" "name2" begin end + msg2 = """Multiple testset types provided to @testset. \ + This is deprecated and may error in the future.""" + @test_deprecated msg2 @macroexpand @testset DefaultTestSet DefaultTestSet begin end end diff --git a/stdlib/libLLVM_jll/Project.toml b/stdlib/libLLVM_jll/Project.toml index f6d93dcb94042..a0eac13b3ab23 100644 --- a/stdlib/libLLVM_jll/Project.toml +++ b/stdlib/libLLVM_jll/Project.toml @@ -1,6 +1,6 @@ name = "libLLVM_jll" uuid = "8f36deef-c2a5-5394-99ed-8e07531fb29a" -version = "17.0.6+4" +version = "18.1.7+2" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" diff --git a/stdlib/libblastrampoline_jll/Project.toml b/stdlib/libblastrampoline_jll/Project.toml index 1d24d2470db2d..1dd22b7fb8d40 100644 --- a/stdlib/libblastrampoline_jll/Project.toml +++ b/stdlib/libblastrampoline_jll/Project.toml @@ -1,6 +1,6 @@ name = "libblastrampoline_jll" uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" -version = "5.10.1+0" +version = "5.11.0+0" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" diff --git a/test/abstractarray.jl b/test/abstractarray.jl index 8efe2e64b606c..8b4a1d9113940 100644 --- a/test/abstractarray.jl +++ b/test/abstractarray.jl @@ -1436,6 +1436,15 @@ using .Main.OffsetArrays end end +@testset "Check push!($a, $args...)" for + a in (["foo", "Bar"], SimpleArray(["foo", "Bar"]), OffsetVector(["foo", "Bar"], 0:1)), + args in (("eenie",), ("eenie", "minie"), ("eenie", "minie", "mo")) + orig = copy(a) + push!(a, args...) + @test length(a) == length(orig) + length(args) + @test all(a[end-length(args)+1:end] .== args) +end + @testset "splatting into hvcat" begin t = (1, 2) @test [t...; 3 4] == [1 2; 3 4] diff --git a/test/ambiguous.jl b/test/ambiguous.jl index d6f69f21bcdce..acdfdc70ba30c 100644 --- a/test/ambiguous.jl +++ b/test/ambiguous.jl @@ -447,4 +447,20 @@ cc46601(::Type{T}, x::Int) where {T<:AbstractString} = 7 @test length(methods(cc46601, Tuple{Type{<:Integer}, Integer})) == 2 @test length(Base.methods_including_ambiguous(cc46601, Tuple{Type{<:Integer}, Integer})) == 7 +# Issue #55231 +struct U55231{P} end +struct V55231{P} end +U55231(::V55231) = nothing +(::Type{T})(::V55231) where {T<:U55231} = nothing +@test length(methods(U55231)) == 2 +U55231(a, b) = nothing +@test length(methods(U55231)) == 3 +struct S55231{P} end +struct T55231{P} end +(::Type{T})(::T55231) where {T<:S55231} = nothing +S55231(::T55231) = nothing +@test length(methods(S55231)) == 2 +S55231(a, b) = nothing +@test length(methods(S55231)) == 3 + nothing diff --git a/test/arrayops.jl b/test/arrayops.jl index f4bb2dc7372f8..f58fdb36942a2 100644 --- a/test/arrayops.jl +++ b/test/arrayops.jl @@ -308,6 +308,35 @@ end @test_throws ArgumentError dropdims(a, dims=4) @test_throws ArgumentError dropdims(a, dims=6) + + a = rand(8, 7) + @test @inferred(insertdims(a, dims=1)) == @inferred(insertdims(a, dims=(1,))) == reshape(a, (1, 8, 7)) + @test @inferred(insertdims(a, dims=3)) == @inferred(insertdims(a, dims=(3,))) == reshape(a, (8, 7, 1)) + @test @inferred(insertdims(a, dims=(1, 3))) == reshape(a, (1, 8, 1, 7)) + @test @inferred(insertdims(a, dims=(1, 2, 3))) == reshape(a, (1, 1, 1, 8, 7)) + @test @inferred(insertdims(a, dims=(1, 4))) == reshape(a, (1, 8, 7, 1)) + @test @inferred(insertdims(a, dims=(1, 3, 5))) == reshape(a, (1, 8, 1, 7, 1)) + @test @inferred(insertdims(a, dims=(1, 2, 4, 6))) == reshape(a, (1, 1, 8, 1, 7, 1)) + @test @inferred(insertdims(a, dims=(1, 3, 4, 6))) == reshape(a, (1, 8, 1, 1, 7, 1)) + @test @inferred(insertdims(a, dims=(1, 4, 6, 3))) == reshape(a, (1, 8, 1, 1, 7, 1)) + @test @inferred(insertdims(a, dims=(1, 3, 5, 6))) == reshape(a, (1, 8, 1, 7, 1, 1)) + + @test_throws ArgumentError insertdims(a, dims=(1, 1, 2, 3)) + @test_throws ArgumentError insertdims(a, dims=(1, 2, 2, 3)) + @test_throws ArgumentError insertdims(a, dims=(1, 2, 3, 3)) + @test_throws UndefKeywordError insertdims(a) + @test_throws ArgumentError insertdims(a, dims=0) + @test_throws ArgumentError insertdims(a, dims=(1, 2, 1)) + @test_throws ArgumentError insertdims(a, dims=4) + @test_throws ArgumentError insertdims(a, dims=6) + + # insertdims and dropdims are inverses + b = rand(1,1,1,5,1,1,7) + for dims in [1, (1,), 2, (2,), 3, (3,), (1,3), (1,2,3), (1,2), (1,3,5), (1,2,5,6), (1,3,5,6), (1,3,5,6), (1,6,5,3)] + @test dropdims(insertdims(a; dims); dims) == a + @test insertdims(dropdims(b; dims); dims) == b + end + sz = (5,8,7) A = reshape(1:prod(sz),sz...) @test A[2:6] == [2:6;] @@ -3219,42 +3248,23 @@ end end end -@testset "Wrapping Memory into Arrays with view and reshape" begin - mem::Memory{Int} = Memory{Int}(undef, 10) .= 11:20 - - @test_throws DimensionMismatch reshape(mem, 10, 10) - @test_throws DimensionMismatch reshape(mem, 5) - @test_throws BoundsError view(mem, 1:10, 1:10) - @test_throws BoundsError view(mem, 1:11) - @test_throws BoundsError view(mem, 3:11) - @test_throws BoundsError view(mem, 0:4) - - @test @inferred(view(mem, 1:5))::Vector{Int} == 11:15 - @test @inferred(view(mem, 1:2))::Vector{Int} == 11:12 - @test @inferred(view(mem, 1:10))::Vector{Int} == 11:20 - @test @inferred(view(mem, 3:8))::Vector{Int} == 13:18 - @test @inferred(view(mem, 20:19))::Vector{Int} == [] - @test @inferred(view(mem, -5:-7))::Vector{Int} == [] - @test @inferred(view(mem, :))::Vector{Int} == mem - @test @inferred(reshape(mem, 5, 2))::Matrix{Int} == reshape(11:20, 5, 2) +@testset "Wrapping Memory into Arrays" begin + mem = Memory{Int}(undef, 10) .= 1 + memref = memoryref(mem) + @test_throws DimensionMismatch Base.wrap(Array, mem, (10, 10)) + @test Base.wrap(Array, mem, (5,)) == ones(Int, 5) + @test Base.wrap(Array, mem, 2) == ones(Int, 2) + @test Base.wrap(Array, memref, 10) == ones(Int, 10) + @test Base.wrap(Array, memref, (2,2,2)) == ones(Int,2,2,2) + @test Base.wrap(Array, mem, (5, 2)) == ones(Int, 5, 2) - # 53990 - @test @inferred(view(mem, unsigned(1):10))::Vector{Int} == 11:20 - - empty_mem = Memory{Module}(undef, 0) - @test_throws BoundsError view(empty_mem, 0:1) - @test_throws BoundsError view(empty_mem, 1:2) - @test_throws DimensionMismatch reshape(empty_mem, 1) - @test_throws DimensionMismatch reshape(empty_mem, 1, 2, 3) - @test_throws ArgumentError reshape(empty_mem, 2^16, 2^16, 2^16, 2^16) - - @test @inferred(view(empty_mem, 1:0))::Vector{Module} == [] - @test @inferred(view(empty_mem, 10:3))::Vector{Module} == [] - @test @inferred(view(empty_mem, :))::Vector{Module} == empty_mem - @test isempty(@inferred(reshape(empty_mem, 0, 7, 1))::Array{Module, 3}) - - offset_inds = OffsetArrays.IdOffsetRange(values=3:6, indices=53:56) - @test @inferred(view(collect(mem), offset_inds)) == view(mem, offset_inds) + memref2 = memoryref(mem, 3) + @test Base.wrap(Array, memref2, (5,)) == ones(Int, 5) + @test Base.wrap(Array, memref2, 2) == ones(Int, 2) + @test Base.wrap(Array, memref2, (2,2,2)) == ones(Int,2,2,2) + @test Base.wrap(Array, memref2, (3, 2)) == ones(Int, 3, 2) + @test_throws DimensionMismatch Base.wrap(Array, memref2, 9) + @test_throws DimensionMismatch Base.wrap(Array, memref2, 10) end @testset "Memory size" begin @@ -3265,3 +3275,9 @@ end @test size(mem, 2) == 1 @test size(mem, 0x2) == 1 end + +@testset "MemoryRef" begin + mem = Memory{Float32}(undef, 3) + ref = memoryref(mem, 2) + @test parent(ref) === mem +end diff --git a/test/atomics.jl b/test/atomics.jl index 3df9e7d0f63c0..165c8dc4e2dfc 100644 --- a/test/atomics.jl +++ b/test/atomics.jl @@ -129,6 +129,7 @@ test_field_operators(ARefxy{Any}(123_10, 123_20)) test_field_operators(ARefxy{Union{Nothing,Int}}(123_10, nothing)) test_field_operators(ARefxy{Complex{Int32}}(123_10, 123_20)) test_field_operators(ARefxy{Complex{Int128}}(123_10, 123_20)) +test_field_operators(ARefxy{Complex{Real}}(123_10, 123_20)) test_field_operators(ARefxy{PadIntA}(123_10, 123_20)) test_field_operators(ARefxy{PadIntB}(123_10, 123_20)) #FIXME: test_field_operators(ARefxy{Int24}(123_10, 123_20)) @@ -317,6 +318,7 @@ test_field_orderings(ARefxy{Any}(true, false), true, false) test_field_orderings(ARefxy{Union{Nothing,Missing}}(nothing, missing), nothing, missing) test_field_orderings(ARefxy{Union{Nothing,Int}}(nothing, 123_1), nothing, 123_1) test_field_orderings(Complex{Int128}(10, 30), Complex{Int128}(20, 40)) +test_field_orderings(Complex{Real}(10, 30), Complex{Real}(20, 40)) test_field_orderings(10.0, 20.0) test_field_orderings(NaN, Inf) @@ -568,6 +570,7 @@ test_global_operators(Any) test_global_operators(Union{Nothing,Int}) test_global_operators(Complex{Int32}) test_global_operators(Complex{Int128}) +test_global_operators(Complex{Real}) test_global_operators(PadIntA) test_global_operators(PadIntB) #FIXME: test_global_operators(Int24) @@ -691,6 +694,7 @@ test_global_orderings(Any, true, false) test_global_orderings(Union{Nothing,Missing}, nothing, missing) test_global_orderings(Union{Nothing,Int}, nothing, 123_1) test_global_orderings(Complex{Int128}, Complex{Int128}(10, 30), Complex{Int128}(20, 40)) +test_global_orderings(Complex{Real}, Complex{Real}(10, 30), Complex{Real}(20, 40)) test_global_orderings(Float64, 10.0, 20.0) test_global_orderings(Float64, NaN, Inf) @@ -844,6 +848,7 @@ test_memory_operators(Any) test_memory_operators(Union{Nothing,Int}) test_memory_operators(Complex{Int32}) test_memory_operators(Complex{Int128}) +test_memory_operators(Complex{Real}) test_memory_operators(PadIntA) test_memory_operators(PadIntB) #FIXME: test_memory_operators(Int24) @@ -1031,6 +1036,7 @@ test_memory_orderings(Any, true, false) test_memory_orderings(Union{Nothing,Missing}, nothing, missing) test_memory_orderings(Union{Nothing,Int}, nothing, 123_1) test_memory_orderings(Complex{Int128}(10, 30), Complex{Int128}(20, 40)) +test_memory_orderings(Complex{Real}(10, 30), Complex{Real}(20, 40)) test_memory_orderings(10.0, 20.0) test_memory_orderings(NaN, Inf) diff --git a/test/broadcast.jl b/test/broadcast.jl index e4309bf81419f..b2232258744ac 100644 --- a/test/broadcast.jl +++ b/test/broadcast.jl @@ -979,6 +979,10 @@ end @test sum(bc, dims=1, init=0) == [5] bc = Broadcast.instantiate(Broadcast.broadcasted(*, ['a','b'], 'c')) @test prod(bc, dims=1, init="") == ["acbc"] + + a = rand(-10:10,32,4); b = rand(-10:10,32,4) + bc = Broadcast.instantiate(Broadcast.broadcasted(+,a,b)) + @test sum(bc; dims = 1, init = 0.0) == sum(collect(bc); dims = 1, init = 0.0) end # treat Pair as scalar: diff --git a/test/ccall.jl b/test/ccall.jl index a406af46f0c34..b10504de21abc 100644 --- a/test/ccall.jl +++ b/test/ccall.jl @@ -1937,7 +1937,10 @@ end # issue #52025 @test Base.unsafe_convert(Ptr{Ptr{Cchar}}, Base.cconvert(Ptr{Ptr{Cchar}}, map(pointer, ["ab"]))) isa Ptr{Ptr{Cchar}} - +#issue #54725 +for A in (reinterpret(UInt, [0]), reshape([0, 0], 1, 2)) + @test pointer(A) == Base.unsafe_convert(Ptr{Cvoid}, A) == Base.unsafe_convert(Ptr{Int}, A) +end # Cglobal with non-static symbols doesn't error function cglobal_non_static1() sym = (:global_var, libccalltest) diff --git a/test/cmdlineargs.jl b/test/cmdlineargs.jl index 01a8acaeaea94..c6720e23739d8 100644 --- a/test/cmdlineargs.jl +++ b/test/cmdlineargs.jl @@ -339,43 +339,37 @@ let exename = `$(Base.julia_cmd()) --startup-file=no --color=no` @test errors_not_signals(`$exename -C invalidtarget`) @test errors_not_signals(`$exename --cpu-target=invalidtarget`) - if Sys.iswindows() - # -t, --threads - code = "print(Threads.threadpoolsize())" - cpu_threads = ccall(:jl_effective_threads, Int32, ()) - @test string(cpu_threads) == - read(`$exename --threads auto -e $code`, String) == - read(`$exename --threads=auto -e $code`, String) == - read(`$exename -tauto -e $code`, String) == - read(`$exename -t auto -e $code`, String) - for nt in (nothing, "1") - withenv("JULIA_NUM_THREADS" => nt) do - @test read(`$exename --threads=2 -e $code`, String) == - read(`$exename -t 2 -e $code`, String) == "2" - end - end - # We want to test oversubscription, but on manycore machines, this can - # actually exhaust limited PID spaces - cpu_threads = max(2*cpu_threads, min(50, 10*cpu_threads)) - if Sys.WORD_SIZE == 32 - cpu_threads = min(cpu_threads, 50) - end - @test read(`$exename -t $cpu_threads -e $code`, String) == string(cpu_threads) - withenv("JULIA_NUM_THREADS" => string(cpu_threads)) do - @test read(`$exename -e $code`, String) == string(cpu_threads) + # -t, --threads + code = "print(Threads.threadpoolsize())" + cpu_threads = ccall(:jl_effective_threads, Int32, ()) + @test string(cpu_threads) == + read(`$exename --threads auto -e $code`, String) == + read(`$exename --threads=auto -e $code`, String) == + read(`$exename -tauto -e $code`, String) == + read(`$exename -t auto -e $code`, String) + for nt in (nothing, "1") + withenv("JULIA_NUM_THREADS" => nt) do + @test read(`$exename --threads=2 -e $code`, String) == + read(`$exename -t 2 -e $code`, String) == "2" end - @test errors_not_signals(`$exename -t 0`) - @test errors_not_signals(`$exename -t -1`) + end + # We want to test oversubscription, but on manycore machines, this can + # actually exhaust limited PID spaces + cpu_threads = max(2*cpu_threads, min(50, 10*cpu_threads)) + if Sys.WORD_SIZE == 32 + cpu_threads = min(cpu_threads, 50) + end + @test read(`$exename -t $cpu_threads -e $code`, String) == string(cpu_threads) + withenv("JULIA_NUM_THREADS" => string(cpu_threads)) do + @test read(`$exename -e $code`, String) == string(cpu_threads) + end + @test errors_not_signals(`$exename -t 0`) + @test errors_not_signals(`$exename -t -1`) - # Combining --threads and --procs: --threads does propagate - withenv("JULIA_NUM_THREADS" => nothing) do - code = "print(sum(remotecall_fetch(Threads.threadpoolsize, x) for x in procs()))" - @test read(`$exename -p2 -t2 -e $code`, String) == "6" - end - else - @test_skip "Command line tests with -t are flakey on non-Windows OS" - # Known issue: https://github.com/JuliaLang/julia/issues/49154 - # These tests should be fixed and reenabled on all operating systems. + # Combining --threads and --procs: --threads does propagate + withenv("JULIA_NUM_THREADS" => nothing) do + code = "print(sum(remotecall_fetch(Threads.threadpoolsize, x) for x in procs()))" + @test read(`$exename -p2 -t2 -e $code`, String) == "6" end # Combining --threads and invalid -C should yield a decent error diff --git a/test/compiler/AbstractInterpreter.jl b/test/compiler/AbstractInterpreter.jl index 0d475a8259000..d95354cefa80c 100644 --- a/test/compiler/AbstractInterpreter.jl +++ b/test/compiler/AbstractInterpreter.jl @@ -176,7 +176,6 @@ end == Val{6} @newinterp Issue48097Interp @MethodTable ISSUE_48097_MT CC.method_table(interp::Issue48097Interp) = CC.OverlayMethodTable(CC.get_inference_world(interp), ISSUE_48097_MT) -CC.InferenceParams(::Issue48097Interp) = CC.InferenceParams(; unoptimize_throw_blocks=false) function CC.concrete_eval_eligible(interp::Issue48097Interp, @nospecialize(f), result::CC.MethodCallResult, arginfo::CC.ArgInfo, sv::CC.AbsIntState) ret = @invoke CC.concrete_eval_eligible(interp::CC.AbstractInterpreter, diff --git a/test/compiler/codegen.jl b/test/compiler/codegen.jl index 3d719cbc244e4..c74dfbb29d3dd 100644 --- a/test/compiler/codegen.jl +++ b/test/compiler/codegen.jl @@ -697,7 +697,7 @@ mktempdir() do pfx libs_deleted += 1 end @test libs_deleted > 0 - @test readchomp(`$pfx/bin/$(Base.julia_exename()) -e 'print("no codegen!\n")'`) == "no codegen!" + @test readchomp(`$pfx/bin/$(Base.julia_exename()) --startup-file=no -e 'print("no codegen!\n")'`) == "no codegen!" # PR #47343 libs_emptied = 0 @@ -956,3 +956,13 @@ function foonopreds() pkgid.uuid !== nothing ? pkgid.uuid : false end @test foonopreds() !== nothing + +# issue 55396 +struct Incomplete55396 + x::Tuple{Int} + y::Int + @noinline Incomplete55396(x::Int) = new((x,)) +end +let x = Incomplete55396(55396) + @test x.x === (55396,) +end diff --git a/test/compiler/inference.jl b/test/compiler/inference.jl index 2c149b1abf21d..9ae98b884bef4 100644 --- a/test/compiler/inference.jl +++ b/test/compiler/inference.jl @@ -5052,13 +5052,13 @@ g() = empty_nt_values(Base.inferencebarrier(Tuple{})) # to terminate the call. @newinterp RecurseInterpreter let CC = Core.Compiler - function CC.const_prop_entry_heuristic(interp::RecurseInterpreter, result::CC.MethodCallResult, - si::CC.StmtInfo, sv::CC.AbsIntState, force::Bool) + function CC.const_prop_rettype_heuristic(interp::RecurseInterpreter, result::CC.MethodCallResult, + si::CC.StmtInfo, sv::CC.AbsIntState, force::Bool) if result.rt isa CC.LimitedAccuracy return force # allow forced constprop to recurse into unresolved cycles end - return @invoke CC.const_prop_entry_heuristic(interp::CC.AbstractInterpreter, result::CC.MethodCallResult, - si::CC.StmtInfo, sv::CC.AbsIntState, force::Bool) + return @invoke CC.const_prop_rettype_heuristic(interp::CC.AbstractInterpreter, result::CC.MethodCallResult, + si::CC.StmtInfo, sv::CC.AbsIntState, force::Bool) end end Base.@constprop :aggressive type_level_recurse1(x...) = x[1] == 2 ? 1 : (length(x) > 100 ? x : type_level_recurse2(x[1] + 1, x..., x...)) @@ -5866,3 +5866,8 @@ end bar54341(args...) = foo54341(4, args...) @test Core.Compiler.return_type(bar54341, Tuple{Vararg{Int}}) === Int + +# InterConditional rt with Vararg argtypes +fcondvarargs(a, b, c, d) = isa(d, Int64) +gcondvarargs(a, x...) = return fcondvarargs(a, x...) ? isa(a, Int64) : !isa(a, Int64) +@test Core.Compiler.return_type(gcondvarargs, Tuple{Vararg{Any}}) === Bool diff --git a/test/complex.jl b/test/complex.jl index d798cfe16489c..63304652ee7d8 100644 --- a/test/complex.jl +++ b/test/complex.jl @@ -1215,3 +1215,9 @@ end @test !iseven(7+0im) && isodd(7+0im) @test !iseven(6+1im) && !isodd(7+1im) end + +@testset "issue #55266" begin + for T in (Float16, Float32, Float64) + @test isapprox(atanh(1+im*floatmin(T)), Complex{T}(atanh(1+im*big(floatmin(T))))) + end +end diff --git a/test/core.jl b/test/core.jl index 3a3f6e6d1b6cd..4cbb872ce4e50 100644 --- a/test/core.jl +++ b/test/core.jl @@ -5532,9 +5532,6 @@ let a = Base.StringVector(2^17) @test sizeof(c) == 0 end -# issue #53990 / https://github.com/JuliaLang/julia/pull/53896#discussion_r1555087951 -@test Base.StringVector(UInt64(2)) isa Vector{UInt8} - @test_throws ArgumentError eltype(Bottom) # issue #16424, re-evaluating type definitions @@ -7498,6 +7495,13 @@ struct A43411{S, T} end @test isbitstype(A43411{(:a,), Tuple{Int}}) +# issue #55189 +struct A55189{N} + children::NTuple{N,A55189{N}} +end +@test fieldtype(A55189{2}, 1) === Tuple{A55189{2}, A55189{2}} +@assert !isbitstype(A55189{2}) + # issue #44614 struct T44614_1{T} m::T @@ -7568,7 +7572,7 @@ end # issue #31696 foo31696(x::Int8, y::Int8) = 1 foo31696(x::T, y::T) where {T <: Int8} = 2 -@test length(methods(foo31696)) == 1 +@test length(methods(foo31696)) == 2 let T1 = Tuple{Int8}, T2 = Tuple{T} where T<:Int8, a = T1[(1,)], b = T2[(1,)] b .= a @test b[1] == (1,) diff --git a/test/dict.jl b/test/dict.jl index ca8a598de0b81..e327c86521c88 100644 --- a/test/dict.jl +++ b/test/dict.jl @@ -1510,9 +1510,9 @@ end for T in (Int, Float64, String, Symbol) @testset let T=T @test !Core.Compiler.is_consistent(Base.infer_effects(getindex, (Dict{T,Any}, T))) - @test_broken Core.Compiler.is_effect_free(Base.infer_effects(getindex, (Dict{T,Any}, T))) + @test Core.Compiler.is_effect_free(Base.infer_effects(getindex, (Dict{T,Any}, T))) @test !Core.Compiler.is_nothrow(Base.infer_effects(getindex, (Dict{T,Any}, T))) - @test_broken Core.Compiler.is_terminates(Base.infer_effects(getindex, (Dict{T,Any}, T))) + @test Core.Compiler.is_terminates(Base.infer_effects(getindex, (Dict{T,Any}, T))) end end diff --git a/test/file.jl b/test/file.jl index 905692979c958..1ab990a70af77 100644 --- a/test/file.jl +++ b/test/file.jl @@ -1036,7 +1036,7 @@ if !Sys.iswindows() || Sys.windows_version() >= Sys.WINDOWS_VISTA_VER @test_throws Base._UVError("open($(repr(nonexisting_src)), $(Base.JL_O_RDONLY), 0)", Base.UV_ENOENT) cp(nonexisting_src, dst; force=true, follow_symlinks=false) @test_throws Base._UVError("open($(repr(nonexisting_src)), $(Base.JL_O_RDONLY), 0)", Base.UV_ENOENT) cp(nonexisting_src, dst; force=true, follow_symlinks=true) # mv - @test_throws Base._UVError("open($(repr(nonexisting_src)), $(Base.JL_O_RDONLY), 0)", Base.UV_ENOENT) mv(nonexisting_src, dst; force=true) + @test_throws Base._UVError("rename($(repr(nonexisting_src)), $(repr(dst)))", Base.UV_ENOENT) mv(nonexisting_src, dst; force=true) end end diff --git a/test/filesystem.jl b/test/filesystem.jl index 870350dee9f35..036a3dda30cca 100644 --- a/test/filesystem.jl +++ b/test/filesystem.jl @@ -44,7 +44,7 @@ end @testset "Base.Filesystem docstrings" begin undoc = Docs.undocumented_names(Base.Filesystem) @test_broken isempty(undoc) - @test undoc == [:File, :Filesystem, :cptree, :futime, :rename, :sendfile, :unlink] + @test undoc == [:File, :Filesystem, :cptree, :futime, :sendfile, :unlink] end @testset "write return type" begin diff --git a/test/functional.jl b/test/functional.jl index 3436fb8911cc1..84c4098308ebd 100644 --- a/test/functional.jl +++ b/test/functional.jl @@ -235,3 +235,129 @@ end let (:)(a,b) = (i for i in Base.:(:)(1,10) if i%2==0) @test Int8[ i for i = 1:2 ] == [2,4,6,8,10] end + +@testset "Basic tests of Fix1, Fix2, and Fix" begin + function test_fix1(Fix1=Base.Fix1) + increment = Fix1(+, 1) + @test increment(5) == 6 + @test increment(-1) == 0 + @test increment(0) == 1 + @test map(increment, [1, 2, 3]) == [2, 3, 4] + + concat_with_hello = Fix1(*, "Hello ") + @test concat_with_hello("World!") == "Hello World!" + # Make sure inference is good: + @inferred concat_with_hello("World!") + + one_divided_by = Fix1(/, 1) + @test one_divided_by(10) == 1/10.0 + @test one_divided_by(-5) == 1/-5.0 + + return nothing + end + + function test_fix2(Fix2=Base.Fix2) + return_second = Fix2((x, y) -> y, 999) + @test return_second(10) == 999 + @inferred return_second(10) + @test return_second(-5) == 999 + + divide_by_two = Fix2(/, 2) + @test map(divide_by_two, (2, 4, 6)) == (1.0, 2.0, 3.0) + @inferred map(divide_by_two, (2, 4, 6)) + + concat_with_world = Fix2(*, " World!") + @test concat_with_world("Hello") == "Hello World!" + @inferred concat_with_world("Hello World!") + + return nothing + end + + # Test with normal Base.Fix1 and Base.Fix2 + test_fix1() + test_fix2() + + # Now, repeat the Fix1 and Fix2 tests, but + # with a Fix lambda function used in their place + test_fix1((op, arg) -> Base.Fix{1}(op, arg)) + test_fix2((op, arg) -> Base.Fix{2}(op, arg)) + + # Now, we do more complex tests of Fix: + let Fix=Base.Fix + @testset "Argument Fixation" begin + let f = (x, y, z) -> x + y * z + fixed_f1 = Fix{1}(f, 10) + @test fixed_f1(2, 3) == 10 + 2 * 3 + + fixed_f2 = Fix{2}(f, 5) + @test fixed_f2(1, 4) == 1 + 5 * 4 + + fixed_f3 = Fix{3}(f, 3) + @test fixed_f3(1, 2) == 1 + 2 * 3 + end + end + @testset "Helpful errors" begin + let g = (x, y) -> x - y + # Test minimum N + fixed_g1 = Fix{1}(g, 100) + @test fixed_g1(40) == 100 - 40 + + # Test maximum N + fixed_g2 = Fix{2}(g, 100) + @test fixed_g2(150) == 150 - 100 + + # One over + fixed_g3 = Fix{3}(g, 100) + @test_throws ArgumentError("expected at least 2 arguments to `Fix{3}`, but got 1") fixed_g3(1) + end + end + @testset "Type Stability and Inference" begin + let h = (x, y) -> x / y + fixed_h = Fix{2}(h, 2.0) + @test @inferred(fixed_h(4.0)) == 2.0 + end + end + @testset "Interaction with varargs" begin + vararg_f = (x, y, z...) -> x + 10 * y + sum(z; init=zero(x)) + fixed_vararg_f = Fix{2}(vararg_f, 6) + + # Can call with variable number of arguments: + @test fixed_vararg_f(1, 2, 3, 4) == 1 + 10 * 6 + sum((2, 3, 4)) + @inferred fixed_vararg_f(1, 2, 3, 4) + @test fixed_vararg_f(5) == 5 + 10 * 6 + @inferred fixed_vararg_f(5) + end + @testset "Errors should propagate normally" begin + error_f = (x, y) -> sin(x * y) + fixed_error_f = Fix{2}(error_f, Inf) + @test_throws DomainError fixed_error_f(10) + end + @testset "Chaining Fix together" begin + f1 = Fix{1}(*, "1") + f2 = Fix{1}(f1, "2") + f3 = Fix{1}(f2, "3") + @test f3() == "123" + + g1 = Fix{2}(*, "1") + g2 = Fix{2}(g1, "2") + g3 = Fix{2}(g2, "3") + @test g3("") == "123" + end + @testset "Zero arguments" begin + f = Fix{1}(x -> x, 'a') + @test f() == 'a' + end + @testset "Dummy-proofing" begin + @test_throws ArgumentError("expected `N` in `Fix{N}` to be integer greater than 0, but got 0") Fix{0}(>, 1) + @test_throws ArgumentError("expected type parameter in `Fix` to be `Int`, but got `0.5::Float64`") Fix{0.5}(>, 1) + @test_throws ArgumentError("expected type parameter in `Fix` to be `Int`, but got `1::UInt64`") Fix{UInt64(1)}(>, 1) + end + @testset "Specialize to structs not in `Base`" begin + struct MyStruct + x::Int + end + f = Fix{1}(MyStruct, 1) + @test f isa Fix{1,Type{MyStruct},Int} + end + end +end diff --git a/test/llvmcall.jl b/test/llvmcall.jl index 98968bfcdf8bc..c83ac05b1ec48 100644 --- a/test/llvmcall.jl +++ b/test/llvmcall.jl @@ -70,13 +70,13 @@ end ret i32 %3""", Int32, Tuple{Int32, Int32}, Int32(1), Int32(2))) # llvmcall must be compiled to be called -# Test whether declarations work properly +#Since LLVM 18, LLVM does a best effort to automatically include the intrinsics function undeclared_ceil(x::Float64) llvmcall("""%2 = call double @llvm.ceil.f64(double %0) ret double %2""", Float64, Tuple{Float64}, x) end -@test_throws ErrorException undeclared_ceil(4.2) -@test_throws ErrorException undeclared_ceil(4.2) +@test undeclared_ceil(4.2) == 5.0 +@test undeclared_ceil(4.2) == 5.0 function declared_floor(x::Float64) llvmcall( diff --git a/test/llvmpasses/alloc-opt-bits.ll b/test/llvmpasses/alloc-opt-bits.ll new file mode 100644 index 0000000000000..e19093f46f815 --- /dev/null +++ b/test/llvmpasses/alloc-opt-bits.ll @@ -0,0 +1,37 @@ +; This file is a part of Julia. License is MIT: https://julialang.org/license + +; RUN: opt --load-pass-plugin=libjulia-codegen%shlibext -passes='function(AllocOpt)' -S %s | FileCheck %s + + +@tag = external addrspace(10) global {} + +@glob = external addrspace(10) global {} + +; Test that the gc_preserve intrinsics are deleted directly. + +; CHECK-LABEL: @ptr_and_bits +; CHECK-NOT: alloca +; CHECK: call noalias ptr addrspace(10) @julia.gc_alloc_obj + +define void @ptr_and_bits(ptr %fptr, i1 %b, i1 %b2, i32 %idx) { + %pgcstack = call ptr @julia.get_pgcstack() + %ptls = call ptr @julia.ptls_states() + %ptls_i8 = bitcast ptr %ptls to ptr + %v = call noalias ptr addrspace(10) @julia.gc_alloc_obj(ptr %ptls_i8, i64 16, ptr addrspace(10) @tag) + + %g0 = getelementptr { i64, ptr addrspace(10) }, ptr addrspace(10) %v, i32 %idx, i32 1 + store ptr addrspace(10) @glob, ptr addrspace(10) %g0 + + %g1 = getelementptr { i64, ptr addrspace(10) }, ptr addrspace(10) %v, i32 %idx, i32 0 + store i64 7, ptr addrspace(10) %g1 + + %res = load ptr addrspace(10), ptr addrspace(10) %g0 + %res2 = load i64, ptr addrspace(10) %g1 + ret void +} + +declare noalias ptr addrspace(10) @julia.gc_alloc_obj(ptr, i64, ptr addrspace(10)) + +declare ptr @julia.ptls_states() + +declare ptr @julia.get_pgcstack() diff --git a/test/llvmpasses/parsing.ll b/test/llvmpasses/parsing.ll index e75ba292f254a..e0a726176b225 100644 --- a/test/llvmpasses/parsing.ll +++ b/test/llvmpasses/parsing.ll @@ -1,6 +1,9 @@ ; COM: NewPM-only test, tests for ability to parse Julia passes ; RUN: opt --load-pass-plugin=libjulia-codegen%shlibext -passes='module(CPUFeatures,RemoveNI,JuliaMultiVersioning,RemoveJuliaAddrspaces,LowerPTLSPass,function(DemoteFloat16,CombineMulAdd,LateLowerGCFrame,FinalLowerGC,AllocOpt,PropagateJuliaAddrspaces,LowerExcHandlers,GCInvariantVerifier,loop(LowerSIMDLoop,JuliaLICM),GCInvariantVerifier,GCInvariantVerifier),LowerPTLSPass,LowerPTLSPass,JuliaMultiVersioning,JuliaMultiVersioning)' -S %s -o /dev/null +; RUN: opt --load-pass-plugin=libjulia-codegen%shlibext -passes="julia" -S %s -o /dev/null +; RUN: opt --load-pass-plugin=libjulia-codegen%shlibext -passes="julia" -S %s -o /dev/null +; RUN: opt --load-pass-plugin=libjulia-codegen%shlibext -passes="julia" -S %s -o /dev/null define void @test() { ret void diff --git a/test/llvmpasses/pipeline-prints.ll b/test/llvmpasses/pipeline-prints.ll index babd26c797a38..ecb70953026c2 100644 --- a/test/llvmpasses/pipeline-prints.ll +++ b/test/llvmpasses/pipeline-prints.ll @@ -298,12 +298,12 @@ attributes #2 = { inaccessiblemem_or_argmemonly } ; COM: Loop simplification makes the exit condition obvious ; AFTERLOOPSIMPLIFICATION: L35.lr.ph: -; AFTERLOOPSIMPLIFICATION-NEXT: add nuw nsw +; AFTERLOOPSIMPLIFICATION: add nuw nsw ; COM: Scalar optimization removes the previous add from the preheader -; AFTERSCALAROPTIMIZATION: L35.preheader: +; AFTERSCALAROPTIMIZATION: L35.lr.ph: ; AFTERSCALAROPTIMIZATION-NOT: add nuw nsw -; AFTERSCALAROPTIMIZATION-NEXT: br label %L35 +; AFTERSCALAROPTIMIZATION: br label %L35 ; COM: Vectorization does stuff ; AFTERVECTORIZATION: vector.body diff --git a/test/namedtuple.jl b/test/namedtuple.jl index 0487f96496309..b8dba5c06422e 100644 --- a/test/namedtuple.jl +++ b/test/namedtuple.jl @@ -1,5 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +using Base: delete + @test_throws TypeError NamedTuple{1,Tuple{}} @test_throws TypeError NamedTuple{(),1} @test_throws TypeError NamedTuple{(:a,1),Tuple{Int}} @@ -282,6 +284,11 @@ end abstr_nt_22194_3() @test Base.return_types(abstr_nt_22194_3, ()) == Any[Any] +@test delete((a=1,), :a) == NamedTuple() +@test delete((a=1, b=2), :a) == (b=2,) +@test delete((a=1, b=2, c=3), :b) == (a=1, c=3) +@test delete((a=1, b=2, c=3), :z) == (a=1, b=2, c=3) + @test Base.structdiff((a=1, b=2), (b=3,)) == (a=1,) @test Base.structdiff((a=1, b=2, z=20), (b=3,)) == (a=1, z=20) @test Base.structdiff((a=1, b=2, z=20), (b=3, q=20, z=1)) == (a=1,) diff --git a/test/offsetarray.jl b/test/offsetarray.jl index 9d6a8b08c0b1f..c50f38c382385 100644 --- a/test/offsetarray.jl +++ b/test/offsetarray.jl @@ -865,6 +865,15 @@ end @test CartesianIndices(A) == CartesianIndices(B) end +@testset "overflowing show" begin + A = OffsetArray(repeat([1], 1), typemax(Int)-1) + b = IOBuffer(maxsize=10) + show(b, A) + @test String(take!(b)) == "[1]" + show(b, (A, A)) + @test String(take!(b)) == "([1], [1])" +end + @testset "indexing views (#53249)" begin v = view([1,2,3,4], :) @test v[Base.IdentityUnitRange(2:3)] == OffsetArray(2:3, 2:3) diff --git a/test/precompile.jl b/test/precompile.jl index 3241ee8b25a35..f45eb4bb1e79e 100644 --- a/test/precompile.jl +++ b/test/precompile.jl @@ -597,6 +597,10 @@ precompile_test_harness(false) do dir @test Base.invokelatest(Baz.baz) === 1 @test Baz === UseBaz.Baz + # should not throw if the cachefile does not exist + @test !isfile("DoesNotExist.ji") + @test Base.stale_cachefile("", "DoesNotExist.ji") === true + # Issue #12720 FooBar1_file = joinpath(dir, "FooBar1.jl") write(FooBar1_file, diff --git a/test/reducedim.jl b/test/reducedim.jl index 8f629fa83f28d..6a6f20214058c 100644 --- a/test/reducedim.jl +++ b/test/reducedim.jl @@ -587,6 +587,30 @@ end @test B[argmin(B, dims=[2, 3])] == @inferred(minimum(B, dims=[2, 3])) end +@testset "careful with @inbounds" begin + Base.@propagate_inbounds f(x) = x == 2 ? x[-10000] : x + Base.@propagate_inbounds op(x,y) = x[-10000] + y[-10000] + for (arr, dims) in (([1,1,2], 1), ([1 1 2], 2), ([ones(Int,256);2], 1)) + @test_throws BoundsError mapreduce(f, +, arr) + @test_throws BoundsError mapreduce(f, +, arr; dims) + @test_throws BoundsError mapreduce(f, +, arr; dims, init=0) + @test_throws BoundsError mapreduce(identity, op, arr) + try + #=@test_throws BoundsError=# mapreduce(identity, op, arr; dims) + catch ex + @test_broken ex isa BoundsError + end + @test_throws BoundsError mapreduce(identity, op, arr; dims, init=0) + + @test_throws BoundsError findmin(f, arr) + @test_throws BoundsError findmin(f, arr; dims) + + @test_throws BoundsError mapreduce(f, max, arr) + @test_throws BoundsError mapreduce(f, max, arr; dims) + @test_throws BoundsError mapreduce(f, max, arr; dims, init=0) + end +end + @testset "in-place reductions with mismatched dimensionalities" begin B = reshape(1:24, 4, 3, 2) for R in (fill(0, 4), fill(0, 4, 1), fill(0, 4, 1, 1)) diff --git a/test/reflection.jl b/test/reflection.jl index ef940b034a2e1..634390e0680d1 100644 --- a/test/reflection.jl +++ b/test/reflection.jl @@ -686,7 +686,7 @@ let @test @inferred wrapperT(ReflectionExample{T, Int64} where T) == ReflectionExample @test @inferred wrapperT(ReflectionExample) == ReflectionExample @test @inferred wrapperT(Union{ReflectionExample{Union{},1},ReflectionExample{Float64,1}}) == ReflectionExample - @test_throws(ErrorException("typename does not apply to unions whose components have different typenames"), + @test_throws(Core.TypeNameError(Union{Int, Float64}), Base.typename(Union{Int, Float64})) end diff --git a/test/specificity.jl b/test/specificity.jl index 816a59f63e193..13688036c2047 100644 --- a/test/specificity.jl +++ b/test/specificity.jl @@ -316,3 +316,14 @@ end @test args_morespecific(Tuple{typeof(Union{}), Any}, Tuple{Any, Type{Union{}}}) @test args_morespecific(Tuple{Type{Union{}}, Type{Union{}}, Any}, Tuple{Type{Union{}}, Any, Type{Union{}}}) @test args_morespecific(Tuple{Type{Union{}}, Type{Union{}}, Any, Type{Union{}}}, Tuple{Type{Union{}}, Any, Type{Union{}}, Type{Union{}}}) + +# requires assertions enabled +let root = NTuple + N = root.var + T = root.body.var + x1 = root.body.body + x2 = Dict{T,Tuple{N}} + A = UnionAll(N, UnionAll(T, Tuple{Union{x1, x2}})) + B = Tuple{Union{UnionAll(N, UnionAll(T, x1)), UnionAll(N, UnionAll(T, x2))}} + @ccall jl_type_morespecific_no_subtype(A::Any, B::Any)::Cint +end diff --git a/test/strings/io.jl b/test/strings/io.jl index f1fe0c24e8aea..209844580b3cd 100644 --- a/test/strings/io.jl +++ b/test/strings/io.jl @@ -165,6 +165,11 @@ @test Base.escape_raw_string(raw"some\"string\\", '`') == "some\"string\\\\" @test Base.escape_raw_string(raw"some\"string") == "some\\\"string" @test Base.escape_raw_string(raw"some`string", '`') == "some\\`string" + + # ascii and fullhex flags: + @test escape_string("\u00e4\u00f6\u00fc") == "\u00e4\u00f6\u00fc" + @test escape_string("\u00e4\u00f6\u00fc", ascii=true) == "\\ue4\\uf6\\ufc" + @test escape_string("\u00e4\u00f6\u00fc", ascii=true, fullhex=true) == "\\u00e4\\u00f6\\u00fc" end @testset "join()" begin @test join([]) == join([],",") == "" @@ -339,3 +344,8 @@ end @testset "`string` return types" begin @test all(T -> T <: AbstractString, Base.return_types(string)) end + +@testset "type stable `join` (#55389)" begin + itr = ("foo" for _ in 1:100) + @test Base.return_types(join, (typeof(itr),))[] == String +end diff --git a/test/strings/util.jl b/test/strings/util.jl index 59638dc3b9ca6..ae16e24f4ea8b 100644 --- a/test/strings/util.jl +++ b/test/strings/util.jl @@ -2,6 +2,20 @@ SubStr(s) = SubString("abc$(s)de", firstindex(s) + 3, lastindex(s) + 3) +@testset "textwidth" begin + for (c, w) in [('x', 1), ('α', 1), ('🍕', 2), ('\0', 0), ('\u0302', 0), ('\xc0', 1)] + @test textwidth(c) == w + @test textwidth(c^3) == w*3 + @test w == @invoke textwidth(c::AbstractChar) + end + for i in 0x00:0x7f # test all ASCII chars (which have fast path) + w = Int(ccall(:utf8proc_charwidth, Cint, (UInt32,), i)) + c = Char(i) + @test textwidth(c) == w + @test w == @invoke textwidth(c::AbstractChar) + end +end + @testset "padding (lpad and rpad)" begin @test lpad("foo", 2) == "foo" @test rpad("foo", 2) == "foo" @@ -53,6 +67,52 @@ SubStr(s) = SubString("abc$(s)de", firstindex(s) + 3, lastindex(s) + 3) @test rpad("⟨k|H₁|k⟩", 12) |> textwidth == 12 end +@testset "string truncation (ltruncate, rtruncate, ctruncate)" begin + @test ltruncate("foo", 4) == "foo" + @test ltruncate("foo", 3) == "foo" + @test ltruncate("foo", 2) == "…o" + @test ltruncate("🍕🍕 I love 🍕", 10) == "…I love 🍕" # handle wide emojis + @test ltruncate("🍕🍕 I love 🍕", 10, "[…]") == "[…]love 🍕" + # when the replacement string is longer than the trunc + # trust that the user wants the replacement string rather than erroring + @test ltruncate("abc", 2, "xxxxxx") == "xxxxxx" + + @inferred ltruncate("xxx", 4) + @inferred ltruncate("xxx", 2) + @inferred ltruncate(@view("xxxxxxx"[1:4]), 4) + @inferred ltruncate(@view("xxxxxxx"[1:4]), 2) + + @test rtruncate("foo", 4) == "foo" + @test rtruncate("foo", 3) == "foo" + @test rtruncate("foo", 2) == "f…" + @test rtruncate("🍕🍕 I love 🍕", 10) == "🍕🍕 I lo…" + @test rtruncate("🍕🍕 I love 🍕", 10, "[…]") == "🍕🍕 I […]" + @test rtruncate("abc", 2, "xxxxxx") == "xxxxxx" + + @inferred rtruncate("xxx", 4) + @inferred rtruncate("xxx", 2) + @inferred rtruncate(@view("xxxxxxx"[1:4]), 4) + @inferred rtruncate(@view("xxxxxxx"[1:4]), 2) + + @test ctruncate("foo", 4) == "foo" + @test ctruncate("foo", 3) == "foo" + @test ctruncate("foo", 2) == "f…" + @test ctruncate("foo", 2; prefer_left=true) == "f…" + @test ctruncate("foo", 2; prefer_left=false) == "…o" + @test ctruncate("foobar", 6) == "foobar" + @test ctruncate("foobar", 5) == "fo…ar" + @test ctruncate("foobar", 4) == "fo…r" + @test ctruncate("🍕🍕 I love 🍕", 10) == "🍕🍕 …e 🍕" + @test ctruncate("🍕🍕 I love 🍕", 10, "[…]") == "🍕🍕[…] 🍕" + @test ctruncate("abc", 2, "xxxxxx") == "xxxxxx" + @test ctruncate("🍕🍕🍕🍕🍕🍕xxxxxxxxxxx", 9) == "🍕🍕…xxxx" + + @inferred ctruncate("xxxxx", 5) + @inferred ctruncate("xxxxx", 3) + @inferred ctruncate(@view("xxxxxxx"[1:5]), 5) + @inferred ctruncate(@view("xxxxxxx"[1:5]), 3) +end + # string manipulation @testset "lstrip/rstrip/strip" begin @test strip("") == "" diff --git a/test/subtype.jl b/test/subtype.jl index c26f4fc9d30e2..7be869107b432 100644 --- a/test/subtype.jl +++ b/test/subtype.jl @@ -707,16 +707,17 @@ macro testintersect(a, b, result) a = esc(a) b = esc(b) result = esc(result) - Base.remove_linenums!(quote + # use a manual macrocall expression since Test will examine this __source__ value + return quote # test real intersect - @test $cmp(_type_intersect($a, $b), $result) - @test $cmp(_type_intersect($b, $a), $result) + $(Expr(:macrocall, :var"@test", __source__, :($cmp(_type_intersect($a, $b), $result)))) + $(Expr(:macrocall, :var"@test", __source__, :($cmp(_type_intersect($b, $a), $result)))) # test simplified intersect if !($result === Union{}) - @test typeintersect($a, $b) != Union{} - @test typeintersect($b, $a) != Union{} + $(Expr(:macrocall, :var"@test", __source__, :(typeintersect($a, $b) != Union{}))) + $(Expr(:macrocall, :var"@test", __source__, :(typeintersect($b, $a) != Union{}))) end - end) + end end abstract type IT4805_2{N, T} end @@ -2267,31 +2268,46 @@ let S = Tuple{Integer, U} where {II<:Array, U<:Tuple{Vararg{II, 1}}} @testintersect(S, Tuple{Int, U} where {N, U<:Tuple{Any,Any,Vararg{Any,N}}}, Union{}) end +function equal_envs(env1, env2) + length(env1) == length(env2) || return false + for i = 1:length(env1) + a = env1[i] + b = env2[i] + if a isa TypeVar + if !(b isa TypeVar && a.name == b.name && a.lb == b.lb && a.ub == b.ub) + return false + end + elseif !(a == b) + return false + end + end + return true +end + # issue #43064 let - env_tuple(@nospecialize(x), @nospecialize(y)) = (intersection_env(x, y)[2]...,) - all_var(x::UnionAll) = (x.var, all_var(x.body)...) - all_var(x::DataType) = () + env_tuple(@nospecialize(x), @nospecialize(y)) = intersection_env(x, y)[2] TT0 = Tuple{Type{T},Union{Real,Missing,Nothing}} where {T} TT1 = Union{Type{Int8},Type{Int16}} @test env_tuple(Tuple{TT1,Missing}, TT0) === env_tuple(Tuple{TT1,Nothing}, TT0) === - env_tuple(Tuple{TT1,Int}, TT0) === all_var(TT0) + env_tuple(Tuple{TT1,Int}, TT0) === + Core.svec(TT0.var) TT0 = Tuple{T1,T2,Union{Real,Missing,Nothing}} where {T1,T2} TT1 = Tuple{T1,T2,Union{Real,Missing,Nothing}} where {T2,T1} TT2 = Tuple{Union{Int,Int8},Union{Int,Int8},Int} TT3 = Tuple{Int,Union{Int,Int8},Int} - @test env_tuple(TT2, TT0) === all_var(TT0) - @test env_tuple(TT2, TT1) === all_var(TT1) - @test env_tuple(TT3, TT0) === Base.setindex(all_var(TT0), Int, 1) - @test env_tuple(TT3, TT1) === Base.setindex(all_var(TT1), Int, 2) + @test equal_envs(env_tuple(TT2, TT0), Core.svec(TypeVar(:T1, Union{Int, Int8}), TypeVar(:T2, Union{Int, Int8}))) + @test equal_envs(env_tuple(TT2, TT1), Core.svec(TypeVar(:T2, Union{Int, Int8}), TypeVar(:T1, Union{Int, Int8}))) + @test equal_envs(env_tuple(TT3, TT0), Core.svec(Int, TypeVar(:T2, Union{Int, Int8}))) + @test equal_envs(env_tuple(TT3, TT1), Core.svec(TypeVar(:T2, Union{Int, Int8}), Int)) TT0 = Tuple{T1,T2,T1,Union{Real,Missing,Nothing}} where {T1,T2} TT1 = Tuple{T1,T2,T1,Union{Real,Missing,Nothing}} where {T2,T1} TT2 = Tuple{Int,Union{Int,Int8},Int,Int} - @test env_tuple(TT2, TT0) === Base.setindex(all_var(TT0), Int, 1) - @test env_tuple(TT2, TT1) === Base.setindex(all_var(TT1), Int, 2) + @test equal_envs(env_tuple(TT2, TT0), Core.svec(Int, TypeVar(:T2, Union{Int, Int8}))) + @test equal_envs(env_tuple(TT2, TT1), Core.svec(TypeVar(:T2, Union{Int, Int8}), Int)) end #issue #46735 @@ -2380,12 +2396,41 @@ let S = Tuple{T2, V2} where {T2, N2, V2<:(Array{S2, N2} where {S2 <: T2})}, @testintersect(S, T, !Union{}) end -# A simple case which has a small local union. -# make sure the env is not widened too much when we intersect(Int8, Int8). -struct T48006{A1,A2,A3} end -@testintersect(Tuple{T48006{Float64, Int, S1}, Int} where {F1<:Real, S1<:Union{Int8, Val{F1}}}, - Tuple{T48006{F2, I, S2}, I} where {F2<:Real, I<:Int, S2<:Union{Int8, Val{F2}}}, - Tuple{T48006{Float64, Int, S1}, Int} where S1<:Union{Val{Float64}, Int8}) +let S = Dict{Int, S1} where {F1, S1<:Union{Int8, Val{F1}}}, + T = Dict{F2, S2} where {F2, S2<:Union{Int8, Val{F2}}} + @test_broken typeintersect(S, T) == Dict{Int, S} where S<:Union{Val{Int}, Int8} + @test typeintersect(T, S) == Dict{Int, S} where S<:Union{Val{Int}, Int8} +end + +# Ensure inner `intersect_all` never under-esitimate. +let S = Tuple{F1, Dict{Int, S1}} where {F1, S1<:Union{Int8, Val{F1}}}, + T = Tuple{Any, Dict{F2, S2}} where {F2, S2<:Union{Int8, Val{F2}}} + @test Tuple{Nothing, Dict{Int, Int8}} <: S + @test Tuple{Nothing, Dict{Int, Int8}} <: T + @test Tuple{Nothing, Dict{Int, Int8}} <: typeintersect(S, T) + @test Tuple{Nothing, Dict{Int, Int8}} <: typeintersect(T, S) +end + +let S = Tuple{F1, Val{S1}} where {F1, S1<:Dict{F1}} + T = Tuple{Any, Val{S2}} where {F2, S2<:Union{map(T->Dict{T}, Base.BitInteger_types)...}} + ST = typeintersect(S, T) + TS = typeintersect(S, T) + for U in Base.BitInteger_types + @test Tuple{U, Val{Dict{U,Nothing}}} <: S + @test Tuple{U, Val{Dict{U,Nothing}}} <: T + @test Tuple{U, Val{Dict{U,Nothing}}} <: ST + @test Tuple{U, Val{Dict{U,Nothing}}} <: TS + end +end + +#issue 55206 +struct T55206{A,B<:Complex{A},C<:Union{Dict{Nothing},Dict{A}}} end +@testintersect(T55206, T55206{<:Any,<:Any,<:Dict{Nothing}}, T55206{A,<:Complex{A},<:Dict{Nothing}} where {A}) +@testintersect( + Tuple{Dict{Int8, Int16}, Val{S1}} where {F1, S1<:AbstractSet{F1}}, + Tuple{Dict{T1, T2}, Val{S2}} where {T1, T2, S2<:Union{Set{T1},Set{T2}}}, + Tuple{Dict{Int8, Int16}, Val{S1}} where {S1<:Union{Set{Int8},Set{Int16}}} +) f48167(::Type{Val{L2}}, ::Type{Union{Val{L1}, Set{R}}}) where {L1, R, L2<:L1} = 1 f48167(::Type{Val{L1}}, ::Type{Union{Val{L2}, Set{R}}}) where {L1, R, L2<:L1} = 2 @@ -2554,7 +2599,7 @@ end let T = Tuple{Union{Type{T}, Type{S}}, Union{Val{T}, Val{S}}, Union{Val{T}, S}} where T<:Val{A} where A where S<:Val, S = Tuple{Type{T}, T, Val{T}} where T<:(Val{S} where S<:Val) # optimal = Union{}? - @test typeintersect(T, S) == Tuple{Type{A}, Union{Val{A}, Val{S} where S<:Union{Val, A}, Val{x} where x<:Val, Val{x} where x<:Union{Val, A}}, Val{A}} where A<:(Val{S} where S<:Val) + @test typeintersect(T, S) == Tuple{Type{T}, Union{Val{T}, Val{S}}, Val{T}} where {S<:Val, T<:Val} @test typeintersect(S, T) == Tuple{Type{T}, Union{Val{T}, Val{S}}, Val{T}} where {T<:Val, S<:(Union{Val{A}, Val} where A)} end @@ -2657,3 +2702,22 @@ let S = Tuple{Val{<:T}, Union{Int,T}} where {T}, @testintersect(S, T, !Union{}) @test !Base.has_free_typevars(typeintersect(S, T)) end + +#issue 55230 +let T1 = NTuple{12, Union{Val{1}, Val{2}, Val{3}, Val{4}, Val{5}, Val{6}}} + T2 = Tuple{<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any} + @test T1 <: T2 + T2 = Tuple{<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Val} + @test T1 <: T2 + T2 = Tuple{<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Real} + @test !(T1 <: T2) + T2 = Tuple{<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Union{Val,Real}} + @test T1 <: T2 + T2 = Tuple{<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Union{String,Real}} + @test !(T1 <: T2) + T2 = Tuple{<:Union{Val,Real},<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any} + @test T1 <: T2 + T2 = Tuple{<:Union{String,Real},<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any,<:Any} + @test !(T1 <: T2) + @test Tuple{Union{Val{1},Val{2}}} <: Tuple{S} where {T, S<:Val{T}} +end diff --git a/test/testhelpers/SizedArrays.jl b/test/testhelpers/SizedArrays.jl index bc02fb5cbbd20..a435ca7591cac 100644 --- a/test/testhelpers/SizedArrays.jl +++ b/test/testhelpers/SizedArrays.jl @@ -64,6 +64,10 @@ function Base.similar(::Type{A}, shape::Tuple{SOneTo, Vararg{SOneTo}}) where {A< R = similar(A, length.(shape)) SizedArray{length.(shape)}(R) end +function Base.similar(x::SizedArray, ::Type{T}, shape::Tuple{SOneTo, Vararg{SOneTo}}) where {T} + sz = map(length, shape) + SizedArray{sz}(similar(parent(x), T, sz)) +end const SizedMatrixLike = Union{SizedMatrix, Transpose{<:Any, <:SizedMatrix}, Adjoint{<:Any, <:SizedMatrix}} diff --git a/test/threads.jl b/test/threads.jl index 24da56e2b89fd..7b4558091022b 100644 --- a/test/threads.jl +++ b/test/threads.jl @@ -357,12 +357,12 @@ end @testset "jl_*affinity" begin cpumasksize = @ccall uv_cpumask_size()::Cint - if !Sys.iswindows() && cpumasksize > 0 # otherwise affinities are not supported on the platform (UV_ENOTSUP) - mask = zeros(Cchar, cpumasksize); + if cpumasksize > 0 # otherwise affinities are not supported on the platform (UV_ENOTSUP) jl_getaffinity = (tid, mask, cpumasksize) -> ccall(:jl_getaffinity, Int32, (Int16, Ptr{Cchar}, Int32), tid, mask, cpumasksize) jl_setaffinity = (tid, mask, cpumasksize) -> ccall(:jl_setaffinity, Int32, (Int16, Ptr{Cchar}, Int32), tid, mask, cpumasksize) - @test jl_getaffinity(1, mask, cpumasksize) == 0 - fill!(mask, 1) - @test jl_setaffinity(1, mask, cpumasksize) == 0 + mask = zeros(Cchar, cpumasksize) + @test jl_getaffinity(0, mask, cpumasksize) == 0 + @test !all(iszero, mask) + @test jl_setaffinity(0, mask, cpumasksize) == 0 end end