diff --git a/Makefile b/Makefile index 3991ced0f679b..6a220b0494fec 100644 --- a/Makefile +++ b/Makefile @@ -649,7 +649,7 @@ win-extras: ifeq ($(USE_SYSTEM_LLVM), 1) LLVM_SIZE := llvm-size$(EXE) else -LLVM_SIZE := $(build_depsbindir)/llvm-size$(EXE) +LLVM_SIZE := PATH=$(build_bindir):$$PATH; $(build_depsbindir)/llvm-size$(EXE) endif build-stats: ifeq ($(USE_BINARYBUILDER_LLVM),1) diff --git a/base/Makefile b/base/Makefile index ad2bb6a63ccc0..d27325e7600f8 100644 --- a/base/Makefile +++ b/base/Makefile @@ -243,12 +243,12 @@ endif ifneq (,$(LIBGFORTRAN_VERSION)) $(eval $(call symlink_system_library,CSL,libgfortran,$(LIBGFORTRAN_VERSION))) endif -$(eval $(call symlink_system_library,CSL,libquadmath,0)) $(eval $(call symlink_system_library,CSL,libstdc++,6)) -# We allow libssp, libatomic and libgomp to fail as they are not available on all systems +# We allow libssp, libatomic, libgomp and libquadmath to fail as they are not available on all systems $(eval $(call symlink_system_library,CSL,libssp,0,ALLOW_FAILURE)) $(eval $(call symlink_system_library,CSL,libatomic,1,ALLOW_FAILURE)) $(eval $(call symlink_system_library,CSL,libgomp,1,ALLOW_FAILURE)) +$(eval $(call symlink_system_library,CSL,libquadmath,0,ALLOW_FAILURE)) $(eval $(call symlink_system_library,PCRE,libpcre2-8)) $(eval $(call symlink_system_library,DSFMT,libdSFMT)) $(eval $(call symlink_system_library,LIBBLASTRAMPOLINE,libblastrampoline)) diff --git a/base/abstractarray.jl b/base/abstractarray.jl index 7be13ad34a66d..d7ef5e2b69f2b 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -2891,7 +2891,7 @@ end @inline function _stack_size_check(x, ax1::Tuple) if _iterator_axes(x) != ax1 uax1 = map(UnitRange, ax1) - uaxN = map(UnitRange, axes(x)) + uaxN = map(UnitRange, _iterator_axes(x)) throw(DimensionMismatch( LazyString("stack expects uniform slices, got axes(x) == ", uaxN, " while first had ", uax1))) end diff --git a/base/docs/basedocs.jl b/base/docs/basedocs.jl index b0aadb2b97fff..c802f50493001 100644 --- a/base/docs/basedocs.jl +++ b/base/docs/basedocs.jl @@ -1335,7 +1335,11 @@ Usually `begin` will not be necessary, since keywords such as [`function`](@ref) implicitly begin blocks of code. See also [`;`](@ref). `begin` may also be used when indexing to represent the first index of a -collection or the first index of a dimension of an array. +collection or the first index of a dimension of an array. For example, +`a[begin]` is the first element of an array `a`. + +!!! compat "Julia 1.4" + Use of `begin` as an index requires Julia 1.4 or later. # Examples ```jldoctest @@ -1396,8 +1400,20 @@ kw"struct" mutable struct `mutable struct` is similar to [`struct`](@ref), but additionally allows the -fields of the type to be set after construction. See the manual section on -[Composite Types](@ref) for more information. +fields of the type to be set after construction. + +Individual fields of a mutable struct can be marked as `const` to make them immutable: + +```julia +mutable struct Baz + a::Int + const b::Float64 +end +``` +!!! compat "Julia 1.8" + The `const` keyword for fields of mutable structs requires at least Julia 1.8. + +See the manual section on [Composite Types](@ref) for more information. """ kw"mutable struct" @@ -1747,7 +1763,8 @@ The task will run in the "world age" from the parent at construction when [`sche !!! warning By default tasks will have the sticky bit set to true `t.sticky`. This models the historic default for [`@async`](@ref). Sticky tasks can only be run on the worker thread - they are first scheduled on. To obtain the behavior of [`Threads.@spawn`](@ref) set the sticky + they are first scheduled on, and when scheduled will make the task that they were scheduled + from sticky. To obtain the behavior of [`Threads.@spawn`](@ref) set the sticky bit manually to `false`. # Examples diff --git a/base/expr.jl b/base/expr.jl index e007306063db1..75e54a2249508 100644 --- a/base/expr.jl +++ b/base/expr.jl @@ -795,6 +795,9 @@ while it can not infer the concrete return type of it. Without the `@nospecializeinfer`, `f([1.0])` would infer the return type of `g` as `Float64`, indicating that inference ran for `g(::Vector{Float64})` despite the prohibition on specialized code generation. + +!!! compat "Julia 1.10" + Using `Base.@nospecializeinfer` requires Julia version 1.10. """ macro nospecializeinfer(ex) esc(isa(ex, Expr) ? pushmeta!(ex, :nospecializeinfer) : ex) diff --git a/base/loading.jl b/base/loading.jl index c6405e8c5b37e..a8e3549da5260 100644 --- a/base/loading.jl +++ b/base/loading.jl @@ -3005,7 +3005,13 @@ end return stale_cachefile(PkgId(""), UInt128(0), modpath, cachefile; ignore_loaded) end @constprop :none function stale_cachefile(modkey::PkgId, build_id::UInt128, modpath::String, cachefile::String; ignore_loaded::Bool = false) - 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) diff --git a/base/multidimensional.jl b/base/multidimensional.jl index 050e1503d2e58..b7e95ed7dfba4 100644 --- a/base/multidimensional.jl +++ b/base/multidimensional.jl @@ -1025,25 +1025,34 @@ end ### from abstractarray.jl -# In the common case where we have two views into the same parent, aliasing checks -# are _much_ easier and more important to get right -function mightalias(A::SubArray{T,<:Any,P}, B::SubArray{T,<:Any,P}) where {T,P} - if !_parentsmatch(A.parent, B.parent) - # We cannot do any better than the usual dataids check - return !_isdisjoint(dataids(A), dataids(B)) - end - # Now we know that A.parent === B.parent. This means that the indices of A - # and B are the same length and indexing into the same dimensions. We can - # just walk through them and check for overlaps: O(ndims(A)). We must finally - # ensure that the indices don't alias with either parent - return _indicesmightoverlap(A.indices, B.indices) || - !_isdisjoint(dataids(A.parent), _splatmap(dataids, B.indices)) || - !_isdisjoint(dataids(B.parent), _splatmap(dataids, A.indices)) +function mightalias(A::SubArray, B::SubArray) + # There are three ways that SubArrays might _problematically_ alias one another: + # 1. The parents are the same we can conservatively check if the indices might overlap OR + # 2. The parents alias eachother in a more complicated manner (and we can't trace indices) OR + # 3. One's parent is used in the other's indices + # Note that it's ok for just the indices to alias each other as those should not be mutated, + # so we can always do better than the default !_isdisjoint(dataids(A), dataids(B)) + if isbits(A.parent) || isbits(B.parent) + return false # Quick out for immutables + elseif _parentsmatch(A.parent, B.parent) + # Each SubArray unaliases its own parent from its own indices upon construction, so if + # the two parents are the same, then by construction one cannot alias the other's indices + # and therefore this is the only test we need to perform: + return _indicesmightoverlap(A.indices, B.indices) + else + A_parent_ids = dataids(A.parent) + B_parent_ids = dataids(B.parent) + return !_isdisjoint(A_parent_ids, B_parent_ids) || + !_isdisjoint(A_parent_ids, _splatmap(dataids, B.indices)) || + !_isdisjoint(B_parent_ids, _splatmap(dataids, A.indices)) + end end +# Test if two arrays are backed by exactly the same memory in exactly the same order _parentsmatch(A::AbstractArray, B::AbstractArray) = A === B -# Two reshape(::Array)s of the same size aren't `===` because they have different headers -_parentsmatch(A::Array, B::Array) = pointer(A) == pointer(B) && size(A) == size(B) +_parentsmatch(A::DenseArray, B::DenseArray) = elsize(A) == elsize(B) && pointer(A) == pointer(B) && size(A) == size(B) +_parentsmatch(A::StridedArray, B::StridedArray) = elsize(A) == elsize(B) && pointer(A) == pointer(B) && strides(A) == strides(B) +# Given two SubArrays with the same parent, check if the indices might overlap (returning true if unsure) _indicesmightoverlap(A::Tuple{}, B::Tuple{}) = true _indicesmightoverlap(A::Tuple{}, B::Tuple) = error("malformed subarray") _indicesmightoverlap(A::Tuple, B::Tuple{}) = error("malformed subarray") diff --git a/base/reinterpretarray.jl b/base/reinterpretarray.jl index 3844edc331c7c..4194659c63675 100644 --- a/base/reinterpretarray.jl +++ b/base/reinterpretarray.jl @@ -13,15 +13,16 @@ struct ReinterpretArray{T,N,S,A<:AbstractArray{S},IsReshaped} <: AbstractArray{T function throwbits(S::Type, T::Type, U::Type) @noinline - throw(ArgumentError("cannot reinterpret `$(S)` as `$(T)`, type `$(U)` is not a bits type")) + throw(ArgumentError(LazyString("cannot reinterpret `", S, "` as `", T, "`, type `", U, "` is not a bits type"))) end function throwsize0(S::Type, T::Type, msg) @noinline - throw(ArgumentError("cannot reinterpret a zero-dimensional `$(S)` array to `$(T)` which is of a $msg size")) + throw(ArgumentError(LazyString("cannot reinterpret a zero-dimensional `", S, "` array to `", T, + "` which is of a ", msg, " size"))) end function throwsingleton(S::Type, T::Type) @noinline - throw(ArgumentError("cannot reinterpret a `$(S)` array to `$(T)` which is a singleton type")) + throw(ArgumentError(LazyString("cannot reinterpret a `", S, "` array to `", T, "` which is a singleton type"))) end global reinterpret @@ -50,14 +51,14 @@ struct ReinterpretArray{T,N,S,A<:AbstractArray{S},IsReshaped} <: AbstractArray{T function reinterpret(::Type{T}, a::A) where {T,N,S,A<:AbstractArray{S, N}} function thrownonint(S::Type, T::Type, dim) @noinline - throw(ArgumentError(""" - cannot reinterpret an `$(S)` array to `$(T)` whose first dimension has size `$(dim)`. - The resulting array would have non-integral first dimension. - """)) + throw(ArgumentError(LazyString( + "cannot reinterpret an `", S, "` array to `", T, "` whose first dimension has size `", dim, + "`. The resulting array would have a non-integral first dimension."))) end function throwaxes1(S::Type, T::Type, ax1) @noinline - throw(ArgumentError("cannot reinterpret a `$(S)` array to `$(T)` when the first axis is $ax1. Try reshaping first.")) + throw(ArgumentError(LazyString("cannot reinterpret a `", S, "` array to `", T, + "` when the first axis is ", ax1, ". Try reshaping first."))) end isbitstype(T) || throwbits(S, T, T) isbitstype(S) || throwbits(S, T, S) @@ -82,15 +83,19 @@ struct ReinterpretArray{T,N,S,A<:AbstractArray{S},IsReshaped} <: AbstractArray{T function reinterpret(::typeof(reshape), ::Type{T}, a::A) where {T,S,A<:AbstractArray{S}} function throwintmult(S::Type, T::Type) @noinline - throw(ArgumentError("`reinterpret(reshape, T, a)` requires that one of `sizeof(T)` (got $(sizeof(T))) and `sizeof(eltype(a))` (got $(sizeof(S))) be an integer multiple of the other")) + throw(ArgumentError(LazyString("`reinterpret(reshape, T, a)` requires that one of `sizeof(T)` (got ", + sizeof(T), ") and `sizeof(eltype(a))` (got ", sizeof(S), ") be an integer multiple of the other"))) end function throwsize1(a::AbstractArray, T::Type) @noinline - throw(ArgumentError("`reinterpret(reshape, $T, a)` where `eltype(a)` is $(eltype(a)) requires that `axes(a, 1)` (got $(axes(a, 1))) be equal to 1:$(sizeof(T) ÷ sizeof(eltype(a))) (from the ratio of element sizes)")) + throw(ArgumentError(LazyString("`reinterpret(reshape, ", T, ", a)` where `eltype(a)` is ", eltype(a), + " requires that `axes(a, 1)` (got ", axes(a, 1), ") be equal to 1:", + sizeof(T) ÷ sizeof(eltype(a)), " (from the ratio of element sizes)"))) end function throwfromsingleton(S, T) @noinline - throw(ArgumentError("`reinterpret(reshape, $T, a)` where `eltype(a)` is $S requires that $T be a singleton type, since $S is one")) + throw(ArgumentError(LazyString("`reinterpret(reshape, ", T, ", a)` where `eltype(a)` is ", S, + " requires that ", T, " be a singleton type, since ", S, " is one"))) end isbitstype(T) || throwbits(S, T, T) isbitstype(S) || throwbits(S, T, S) @@ -804,8 +809,8 @@ end inpackedsize = packedsize(In) outpackedsize = packedsize(Out) inpackedsize == outpackedsize || - throw(ArgumentError("Packed sizes of types $Out and $In do not match; got $outpackedsize \ - and $inpackedsize, respectively.")) + throw(ArgumentError(LazyString("Packed sizes of types ", Out, " and ", In, + " do not match; got ", outpackedsize, " and ", inpackedsize, ", respectively."))) in = Ref{In}(x) out = Ref{Out}() if struct_subpadding(Out, In) diff --git a/base/task.jl b/base/task.jl index 137b0f7c4a3f6..ed6d1f507b8f0 100644 --- a/base/task.jl +++ b/base/task.jl @@ -113,6 +113,13 @@ end Wrap an expression in a [`Task`](@ref) without executing it, and return the [`Task`](@ref). This only creates a task, and does not run it. +!!! warning + By default tasks will have the sticky bit set to true `t.sticky`. This models the + historic default for [`@async`](@ref). Sticky tasks can only be run on the worker thread + they are first scheduled on, and when scheduled will make the task that they were scheduled + from sticky. To obtain the behavior of [`Threads.@spawn`](@ref) set the sticky + bit manually to `false`. + # Examples ```jldoctest julia> a1() = sum(i for i in 1:1000); @@ -826,6 +833,13 @@ the woken task. It is incorrect to use `schedule` on an arbitrary `Task` that has already been started. See [the API reference](@ref low-level-schedule-wait) for more information. +!!! warning + By default tasks will have the sticky bit set to true `t.sticky`. This models the + historic default for [`@async`](@ref). Sticky tasks can only be run on the worker thread + they are first scheduled on, and when scheduled will make the task that they were scheduled + from sticky. To obtain the behavior of [`Threads.@spawn`](@ref) set the sticky + bit manually to `false`. + # Examples ```jldoctest julia> a5() = sum(i for i in 1:1000); diff --git a/cli/trampolines/trampolines_aarch64.S b/cli/trampolines/trampolines_aarch64.S index 2d87ae6dcdb1c..ccb9a647ac6c3 100644 --- a/cli/trampolines/trampolines_aarch64.S +++ b/cli/trampolines/trampolines_aarch64.S @@ -5,9 +5,9 @@ #define XX(name) \ .global CNAME(name) SEP \ +CNAME(name)##: SEP \ .cfi_startproc SEP \ .p2align 2 SEP \ -CNAME(name)##: SEP \ adrp x16, PAGE(CNAME(name##_addr)) SEP \ ldr x16, [x16, PAGEOFF(CNAME(name##_addr))] SEP \ br x16 SEP \ diff --git a/deps/blastrampoline.version b/deps/blastrampoline.version index 616300377e3e6..fd055e1ae8120 100644 --- a/deps/blastrampoline.version +++ b/deps/blastrampoline.version @@ -2,6 +2,6 @@ BLASTRAMPOLINE_JLL_NAME := libblastrampoline ## source build -BLASTRAMPOLINE_VER := 5.8.0 -BLASTRAMPOLINE_BRANCH=v5.8.0 -BLASTRAMPOLINE_SHA1=81316155d4838392e8462a92bcac3eebe9acd0c7 +BLASTRAMPOLINE_VER := 5.11.0 +BLASTRAMPOLINE_BRANCH=v5.11.0 +BLASTRAMPOLINE_SHA1=05083d50611b5538df69706f0a952d8e642b0b4b diff --git a/deps/checksums/Pkg-edfa2ed0ea117d61d33405d4214edb6513b3f236.tar.gz/md5 b/deps/checksums/Pkg-edfa2ed0ea117d61d33405d4214edb6513b3f236.tar.gz/md5 new file mode 100644 index 0000000000000..8a9534c09de47 --- /dev/null +++ b/deps/checksums/Pkg-edfa2ed0ea117d61d33405d4214edb6513b3f236.tar.gz/md5 @@ -0,0 +1 @@ +0a9d28868d4ed82d053a586d398ed0ed diff --git a/deps/checksums/Pkg-edfa2ed0ea117d61d33405d4214edb6513b3f236.tar.gz/sha512 b/deps/checksums/Pkg-edfa2ed0ea117d61d33405d4214edb6513b3f236.tar.gz/sha512 new file mode 100644 index 0000000000000..09f6d2b057d65 --- /dev/null +++ b/deps/checksums/Pkg-edfa2ed0ea117d61d33405d4214edb6513b3f236.tar.gz/sha512 @@ -0,0 +1 @@ +8c8bc23cfe2b181cfe37a715057e03dc3d8c811e0480586c6e557a2d9e3fb0f1fef93eef4abc94354e6436ac837bcee8414a5c988a00cba5fe822da9aafcd45f diff --git a/deps/checksums/Pkg-f487626b090b91493828cbcde30eed96fb9f8e8f.tar.gz/md5 b/deps/checksums/Pkg-f487626b090b91493828cbcde30eed96fb9f8e8f.tar.gz/md5 deleted file mode 100644 index 87f249089c1e2..0000000000000 --- a/deps/checksums/Pkg-f487626b090b91493828cbcde30eed96fb9f8e8f.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -9ebc3751d48af21e9f932cfcb3b18781 diff --git a/deps/checksums/Pkg-f487626b090b91493828cbcde30eed96fb9f8e8f.tar.gz/sha512 b/deps/checksums/Pkg-f487626b090b91493828cbcde30eed96fb9f8e8f.tar.gz/sha512 deleted file mode 100644 index c41c5df61579f..0000000000000 --- a/deps/checksums/Pkg-f487626b090b91493828cbcde30eed96fb9f8e8f.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -adeedc81fee8360d427e3870d7b7861d0e653128c59c877ab1173284f19506ff2beeea063281ced3f5411be6a25dcca7c566e16eba21b7e91bbdcb2f5de8e268 diff --git a/deps/checksums/blastrampoline b/deps/checksums/blastrampoline index d72a584fd1b0c..edb8cadc74846 100644 --- a/deps/checksums/blastrampoline +++ b/deps/checksums/blastrampoline @@ -1,34 +1,34 @@ -blastrampoline-81316155d4838392e8462a92bcac3eebe9acd0c7.tar.gz/md5/0478361eac783b99002b1ad985182f05 -blastrampoline-81316155d4838392e8462a92bcac3eebe9acd0c7.tar.gz/sha512/2489ce5770a9861889a2d07e61440ba4f233a92efd4a3544747f83320e0e7a229a8fe01553d99f5f1d98713316f2506daf0adb7d024a46e32b3de1bb2966d637 -libblastrampoline.v5.8.0+1.aarch64-apple-darwin.tar.gz/md5/a28837b9838fef2b3831de3278ec7949 -libblastrampoline.v5.8.0+1.aarch64-apple-darwin.tar.gz/sha512/111ac2fe5f8f8102f2f7c9e9e6aa1d1a12d2db941238c949ff8e64b30335e8b2f6ecce0d5f577879c231eb839c06e259302b709f3d34e94a97047bfa984222f6 -libblastrampoline.v5.8.0+1.aarch64-linux-gnu.tar.gz/md5/9e781a026e03118df81347fb90f10d45 -libblastrampoline.v5.8.0+1.aarch64-linux-gnu.tar.gz/sha512/89469f32a666efd46437351a8fb16758c35e5aecc563d202b480c10ddf9fa5350a5a321076b79b0a1a07ec2cea0b73aa5c28979cc382a198fa96cca0b5899d25 -libblastrampoline.v5.8.0+1.aarch64-linux-musl.tar.gz/md5/b7acda2fdd157bbb183d0dd33643beef -libblastrampoline.v5.8.0+1.aarch64-linux-musl.tar.gz/sha512/cf4125a47334fe2ec0d5a4b11624b12e1366ec031500218f680ad5a53152b9d752c0c02a0b92d0e07f3eb21f2f8f58d0c587438a4869a72197bbd5e91531369d -libblastrampoline.v5.8.0+1.armv6l-linux-gnueabihf.tar.gz/md5/eafabd99fb1287d495acb8efb8091fde -libblastrampoline.v5.8.0+1.armv6l-linux-gnueabihf.tar.gz/sha512/63ff4e6bc400fa8ee713a1c5ae4af0a8e152d49860c6f5e94a17e426ad9f780d41cc0f84d33c75ea5347af1a53f07fc012798d603b6a94ea39f37cfd651a0719 -libblastrampoline.v5.8.0+1.armv6l-linux-musleabihf.tar.gz/md5/9788f74b375ef6b84c16c080f2be5bdd -libblastrampoline.v5.8.0+1.armv6l-linux-musleabihf.tar.gz/sha512/f00ebf794927404e2294a2fbb759b1e3e57836c7f683525fac0b2ac570da2c75904e43f154cf76fce310a624f9b35fbd40e6c7757882bb6f30db790f4221a543 -libblastrampoline.v5.8.0+1.armv7l-linux-gnueabihf.tar.gz/md5/4492bace63d8274d68ecdaa735e47e99 -libblastrampoline.v5.8.0+1.armv7l-linux-gnueabihf.tar.gz/sha512/8868283e6c5224b80145fdfd17f13f713053ba94e49c170f38f0cbf9f794185d7dec9c107ce65dc76121d3ac5b21d2f3857f619d8279bede86a906230ff59a71 -libblastrampoline.v5.8.0+1.armv7l-linux-musleabihf.tar.gz/md5/d66b6ed1d4e5f6a130f36791063e651d -libblastrampoline.v5.8.0+1.armv7l-linux-musleabihf.tar.gz/sha512/414ad07574a6e9aa670bbfea13eaea11da13129c9ccb4193cad708014c31493ff10ff427558b90cb16040fa64c8a325c2e375e3310c39fb37bb3e7fdb6a72a5f -libblastrampoline.v5.8.0+1.i686-linux-gnu.tar.gz/md5/595199a3a01174cfa4d9ce3407bf30dc -libblastrampoline.v5.8.0+1.i686-linux-gnu.tar.gz/sha512/02c3b0c3c0a411d5090a081f3bbbe38aaae40eaa5fe63d0690e0582e233cd9ce76483922557d4f65dc457e29a4e84d86ee5af20a60b082aec7bec4ca8607c1ca -libblastrampoline.v5.8.0+1.i686-linux-musl.tar.gz/md5/5832d0044842cb84f4e1e1b0a04b8205 -libblastrampoline.v5.8.0+1.i686-linux-musl.tar.gz/sha512/d28954d0feef6a33fa0bfeb59acb68821222d36a4e353eaf41936ee2c9aace719c2d0f0b0f080eafe2baecc67a29de4cacc0446aac776bbb615c4426d35c9c8f -libblastrampoline.v5.8.0+1.i686-w64-mingw32.tar.gz/md5/46391ac222980a0ad2c2d6d2b54db26d -libblastrampoline.v5.8.0+1.i686-w64-mingw32.tar.gz/sha512/6dd3434648a297639ef327efa5827d6aea70df551774e52ba395cdf187bfb603d365eed84780913fda5f3d12512ac54ccf784da3cf6317671ab346211f5984b3 -libblastrampoline.v5.8.0+1.powerpc64le-linux-gnu.tar.gz/md5/5f76f5c6a88c0caaa6419ba212f8cb94 -libblastrampoline.v5.8.0+1.powerpc64le-linux-gnu.tar.gz/sha512/785071e682075b2cebd992394e66169f4ee2db3a8e23affb88dc05d9abf55f49d597b2a7400a13c83ad106ad825b5ee666b01f8625e51aec267132573273991e -libblastrampoline.v5.8.0+1.x86_64-apple-darwin.tar.gz/md5/21beb51d448bd22e4608a16b3f4fde05 -libblastrampoline.v5.8.0+1.x86_64-apple-darwin.tar.gz/sha512/620ba64d93ef416e483f813617aa313957282d8361f920b5444702fa911ff0051d1f8a8814b5fa0b082fd4dc77d96cb8b763937c786959bbc97cbb6131617152 -libblastrampoline.v5.8.0+1.x86_64-linux-gnu.tar.gz/md5/14c1045ba4d400f490ddea5343a46f04 -libblastrampoline.v5.8.0+1.x86_64-linux-gnu.tar.gz/sha512/0fdae83f4df93b28951521cf426736367f568c1e76fb68eea42b045cc9a288b6836abb3206a6d61e4f88adcf198553e911c45231aecb0f552e06de28eb3bec54 -libblastrampoline.v5.8.0+1.x86_64-linux-musl.tar.gz/md5/59b110676fcb2fcfdcf670a5d435d555 -libblastrampoline.v5.8.0+1.x86_64-linux-musl.tar.gz/sha512/57a5022e9fabc0637a29f3c32f6180cb4f6a90282191232e299df6cea5265b535e4a0af4fde15c8fe80e5a59edea0fae96dd3a510f5720ecd78e85a2a9ffbfe0 -libblastrampoline.v5.8.0+1.x86_64-unknown-freebsd.tar.gz/md5/c22da112cfc7f9fa0f103d08f4b78965 -libblastrampoline.v5.8.0+1.x86_64-unknown-freebsd.tar.gz/sha512/ace02fac0dc6df472456007a081e0aaa85a6b17290321fb214349aac0f2d0f893df602dca28fc26ddfd4ed574fd9063bacff343249e5a1109f5d92dc9cb7a1d3 -libblastrampoline.v5.8.0+1.x86_64-w64-mingw32.tar.gz/md5/34fdc53745245887f968f420b2f02ed9 -libblastrampoline.v5.8.0+1.x86_64-w64-mingw32.tar.gz/sha512/bbf478736b7bd57b340ccd5b6744d526a7a95fc524d30fdf9af6e9d79285641be26fae5f9e5302d71a5be76b05c379e969a829e259d8100ba9c6ce202b632b3d +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/csl.mk b/deps/csl.mk index aaebc8f50c053..1fb12ad394b12 100644 --- a/deps/csl.mk +++ b/deps/csl.mk @@ -111,6 +111,7 @@ install-csl: cp -a $(build_libdir)/gcc/$(BB_TRIPLET)/13/libgcc.a $(build_private_libdir)/ cp -a $(build_libdir)/gcc/$(BB_TRIPLET)/13/libmsvcrt.a $(build_private_libdir)/ cp -a $(build_libdir)/gcc/$(BB_TRIPLET)/13/libssp.dll.a $(build_private_libdir)/ + cp -a $(build_libdir)/gcc/$(BB_TRIPLET)/13/libssp.dll.a $(build_libdir)/ endif endif ifeq ($(OS),WINNT) @@ -120,4 +121,5 @@ uninstall-gcc-libraries: -rm -f $(build_private_libdir)/libgcc.a -rm -f $(build_private_libdir)/libmsvcrt.a -rm -f $(build_private_libdir)/libssp.dll.a + -rm -f $(build_libdir)/libssp.dll.a endif diff --git a/deps/llvm.mk b/deps/llvm.mk index a06db1fb0781b..8a6f9b7c8e81b 100644 --- a/deps/llvm.mk +++ b/deps/llvm.mk @@ -93,15 +93,14 @@ LLVM_LDFLAGS += $(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 += -DCOMPILER_RT_ENABLE_IOS=OFF -DCOMPILER_RT_ENABLE_WATCHOS=OFF -DCOMPILER_RT_ENABLE_TVOS=OFF +LLVM_CMAKE += -DLLVM_ENABLE_ZLIB=FORCE_ON -DZLIB_ROOT="$(build_prefix)" 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 diff --git a/doc/src/devdocs/build/arm.md b/doc/src/devdocs/build/arm.md index 747ee25d22a04..df9ede07d270f 100644 --- a/doc/src/devdocs/build/arm.md +++ b/doc/src/devdocs/build/arm.md @@ -55,18 +55,9 @@ due to unsupported inline assembly. In that case, add `MCPU=armv7-a` to ## AArch64 (ARMv8) -Julia has been successfully built on the following ARMv8 devices: +Julia is expected to work and build on ARMv8 cpus. One should follow the general [build instructions](https://github.com/JuliaLang/julia/blob/master/README.md). Julia expects to have around 8GB of ram or swap enabled to build itself. -* [nVidia Jetson TX1 & TX2](https://www.nvidia.com/object/embedded-systems-dev-kits-modules.html); -* [X-Gene 1](https://www.apm.com/products/data-center/x-gene-family/x-gene/); -* [Overdrive 3000](https://softiron.com/products/overdrive-3000/); -* [Cavium ThunderX](https://www.cavium.com/ThunderX_ARM_Processors.html) on [packet.net](https://www.packet.net). - -Compilation on `ARMv8-A` requires that `Make.user` is configured as follows: - -``` -MCPU=armv8-a -``` +### Known issues Starting from Julia v1.10, [JITLink](https://llvm.org/docs/JITLink.html) is automatically enabled on this architecture for all operating systems when linking to LLVM 15 or later versions. Due to a [bug in LLVM memory manager](https://github.com/llvm/llvm-project/issues/63236), non-trivial workloads may generate too many memory mappings that on Linux can exceed the limit of memory mappings (`mmap`) set in the file `/proc/sys/vm/max_map_count`, resulting in an error like @@ -77,21 +68,3 @@ Should this happen, ask your system administrator to increase the limit of memor ``` sysctl -w vm.max_map_count=262144 ``` - -### nVidia Jetson TX2 - -Julia builds and runs on the [nVidia Jetson TX2](https://www.nvidia.com/object/embedded-systems-dev-kits-modules.html) -platform with minimal configuration changes. - -After configuring `Make.user` as per the `AArch64` instructions in this document, -follow the general [build instructions](https://github.com/JuliaLang/julia/blob/master/README.md). -The majority of the build dependencies specified in the instructions are installed by -the default configuration flashed by [Jetpack 3.0](https://developer.nvidia.com/embedded/jetpack). The remaining tools can be installed by issuing the following command: - -``` -sudo apt-get install gfortran wget cmake -``` - -A full parallel build, including LLVM, -will complete in around two hours. All tests pass and CUDA functionality is available -through, e.g., [CUDAdrv](https://github.com/JuliaGPU/CUDAdrv.jl). diff --git a/src/Makefile b/src/Makefile index 08fb816d302a0..b91302d384fa7 100644 --- a/src/Makefile +++ b/src/Makefile @@ -119,8 +119,8 @@ ifeq ($(JULIACODEGEN),LLVM) ifneq ($(USE_SYSTEM_LLVM),0) # USE_SYSTEM_LLVM != 0 CG_LLVMLINK += $(LLVM_LDFLAGS) $(shell $(LLVM_CONFIG_HOST) --libs --system-libs) -LLVM_SHLIB_SYMBOL_VERSION := $(shell nm -D --with-symbol-versions $(shell $(LLVM_CONFIG_HOST) --libfiles --link-shared | awk '{print $1; exit}') | \ - grep _ZN4llvm3Any6TypeId | head -n 1 | sed -e 's/.*@//') +LLVM_SHLIB_SYMBOL_VERSION := $(shell readelf -W --dyn-syms $(shell $(LLVM_CONFIG_HOST) --libfiles --link-shared | awk '{print $1; exit}') | \ + grep _ZN4llvm3Any6TypeId | head -n 1 | sed -ne 's/.*@//p') # HACK: llvm-config doesn't correctly point to shared libs on all platforms # https://github.com/JuliaLang/julia/issues/29981 diff --git a/src/jl_uv.c b/src/jl_uv.c index 62dc3a628d085..8bb09636506b9 100644 --- a/src/jl_uv.c +++ b/src/jl_uv.c @@ -39,21 +39,24 @@ static void walk_print_cb(uv_handle_t *h, void *arg) const char *type = uv_handle_type_name(h->type); if (!type) type = ""; + size_t resource_id; // fits an int or pid_t on Unix, HANDLE or PID on Windows uv_os_fd_t fd; if (h->type == UV_PROCESS) - fd = uv_process_get_pid((uv_process_t*)h); - else if (uv_fileno(h, &fd)) - fd = (uv_os_fd_t)-1; + resource_id = (size_t)uv_process_get_pid((uv_process_t*)h); + else if (uv_fileno(h, &fd) == 0) + resource_id = (size_t)fd; + else + resource_id = -1; const char *pad = " "; // 16 spaces - int npad = fd == -1 ? 0 : snprintf(NULL, 0, "%zd", (size_t)fd); + int npad = resource_id == -1 ? 0 : snprintf(NULL, 0, "%zd", resource_id); if (npad < 0) npad = 0; npad += strlen(type); pad += npad < strlen(pad) ? npad : strlen(pad); - if (fd == -1) + if (resource_id == -1) jl_safe_printf(" %s %s%p->%p\n", type, pad, (void*)h, (void*)h->data); else - jl_safe_printf(" %s[%zd] %s%p->%p\n", type, (size_t)fd, pad, (void*)h, (void*)h->data); + jl_safe_printf(" %s[%zd] %s%p->%p\n", type, resource_id, pad, (void*)h, (void*)h->data); } static void wait_empty_func(uv_timer_t *t) diff --git a/src/julia_internal.h b/src/julia_internal.h index fb82a152bffa7..07a1ab628fadf 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -463,6 +463,8 @@ STATIC_INLINE uint8_t JL_CONST_FUNC jl_gc_szclass_align8(unsigned sz) JL_NOTSAFE #define GC_MAX_SZCLASS (2032-sizeof(void*)) static_assert(ARRAY_CACHE_ALIGN_THRESHOLD > GC_MAX_SZCLASS, ""); + +// Size does NOT include the type tag!! STATIC_INLINE jl_value_t *jl_gc_alloc_(jl_ptls_t ptls, size_t sz, void *ty) { jl_value_t *v; diff --git a/src/llvm-alloc-helpers.cpp b/src/llvm-alloc-helpers.cpp index d24c08b4b4930..0acef5557c838 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) @@ -189,6 +191,7 @@ void jl_alloc::runEscapeAnalysis(llvm::Instruction *I, EscapeAnalysisRequiredArg 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(), @@ -280,6 +283,7 @@ void jl_alloc::runEscapeAnalysis(llvm::Instruction *I, EscapeAnalysisRequiredArg 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(), @@ -301,10 +305,14 @@ void jl_alloc::runEscapeAnalysis(llvm::Instruction *I, EscapeAnalysisRequiredArg } 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 3bd80704a0888..0bbf499f9f2f7 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) { } @@ -93,6 +96,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; @@ -107,6 +113,7 @@ namespace jl_alloc { haserror = false; 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 751cae6419dda..f84cb6587cf9f 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); @@ -400,6 +415,8 @@ void Optimizer::insertLifetime(Value *ptr, Constant *sz, Instruction *orig) auto bb = use->getParent(); if (!bbs.insert(bb).second) continue; + if (pred_empty(bb)) + continue; // No predecessors so the block is dead assert(lifetime_stack.empty()); Lifetime::Frame cur{bb}; while (true) { diff --git a/src/llvm-final-gc-lowering.cpp b/src/llvm-final-gc-lowering.cpp index e31bcb21199f5..1cb8caf81e771 100644 --- a/src/llvm-final-gc-lowering.cpp +++ b/src/llvm-final-gc-lowering.cpp @@ -214,7 +214,7 @@ Value *FinalLowerGC::lowerGCAllocBytes(CallInst *target, Function &F) } } else { auto size = builder.CreateZExtOrTrunc(target->getArgOperand(1), T_size); - size = builder.CreateAdd(size, ConstantInt::get(T_size, sizeof(void*))); + // allocTypedFunc does not include the type tag in the allocation size! newI = builder.CreateCall(allocTypedFunc, { ptls, size, ConstantPointerNull::get(Type::getInt8PtrTy(F.getContext())) }); derefAttr = Attribute::getWithDereferenceableBytes(F.getContext(), sizeof(void*)); } diff --git a/src/module.c b/src/module.c index 59bd308d99a41..d39b7e377b2df 100644 --- a/src/module.c +++ b/src/module.c @@ -702,13 +702,15 @@ JL_DLLEXPORT int jl_binding_resolved_p(jl_module_t *m, jl_sym_t *var) static uint_t bindingkey_hash(size_t idx, jl_svec_t *data) { - jl_binding_t *b = (jl_binding_t*)jl_svecref(data, idx); + jl_binding_t *b = (jl_binding_t*)jl_svecref(data, idx); // This must always happen inside the lock jl_sym_t *var = b->globalref->name; return var->hash; } static int bindingkey_eq(size_t idx, const void *var, jl_svec_t *data, uint_t hv) { + if (idx >= jl_svec_len(data)) + return 0; // We got a OOB access, probably due to a data race jl_binding_t *b = (jl_binding_t*)jl_svecref(data, idx); jl_sym_t *name = b->globalref->name; return var == name; diff --git a/src/pipeline.cpp b/src/pipeline.cpp index 88c2da5d729c9..8a9410aa98247 100644 --- a/src/pipeline.cpp +++ b/src/pipeline.cpp @@ -72,7 +72,6 @@ #include #include #include -#include #include #include #include @@ -568,7 +567,6 @@ static void buildPipeline(ModulePassManager &MPM, PassBuilder *PB, OptimizationL if (O.getSpeedupLevel() >= 2) { buildVectorPipeline(FPM, PB, O, options); } - FPM.addPass(WarnMissedTransformationsPass()); MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); } buildIntrinsicLoweringPipeline(MPM, PB, O, options); diff --git a/src/signals-mach.c b/src/signals-mach.c index 6ec8f95570f17..d33e2124bb0fa 100644 --- a/src/signals-mach.c +++ b/src/signals-mach.c @@ -681,16 +681,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 0d5ad9b1be7c5..fe21463a48db8 100644 --- a/src/signals-unix.c +++ b/src/signals-unix.c @@ -899,16 +899,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 diff --git a/src/signals-win.c b/src/signals-win.c index 10bd0dec7f480..25de2e3e821ff 100644 --- a/src/signals-win.c +++ b/src/signals-win.c @@ -420,16 +420,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/threading.c b/src/threading.c index b82e36f66d994..67617da0951dd 100644 --- a/src/threading.c +++ b/src/threading.c @@ -710,7 +710,7 @@ void jl_init_threading(void) jl_atomic_store_release(&jl_all_tls_states, (jl_ptls_t*)calloc(jl_all_tls_states_size, sizeof(jl_ptls_t))); jl_atomic_store_release(&jl_n_threads, jl_all_tls_states_size); jl_n_gcthreads = ngcthreads; - gc_first_tid = nthreads; + gc_first_tid = nthreads + nthreadsi; } static uv_barrier_t thread_init_done; diff --git a/stdlib/Dates/src/types.jl b/stdlib/Dates/src/types.jl index 1d9769a05bd3d..1a80f1408ba54 100644 --- a/stdlib/Dates/src/types.jl +++ b/stdlib/Dates/src/types.jl @@ -183,7 +183,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 8823e56e41a2f..b634f503d4d2f 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/InteractiveUtils/src/editless.jl b/stdlib/InteractiveUtils/src/editless.jl index 539e9b12f4071..1b52caa4cdee3 100644 --- a/stdlib/InteractiveUtils/src/editless.jl +++ b/stdlib/InteractiveUtils/src/editless.jl @@ -223,7 +223,10 @@ Edit a file or directory optionally providing a line number to edit the file at. Return to the `julia` prompt when you quit the editor. The editor can be changed by setting `JULIA_EDITOR`, `VISUAL` or `EDITOR` as an environment variable. -See also [`define_editor`](@ref). +!!! compat "Julia 1.9" + The `column` argument requires at least Julia 1.9. + +See also [`InteractiveUtils.define_editor`](@ref). """ function edit(path::AbstractString, line::Integer=0, column::Integer=0) path isa String || (path = convert(String, path)) diff --git a/stdlib/LinearAlgebra/src/LinearAlgebra.jl b/stdlib/LinearAlgebra/src/LinearAlgebra.jl index 494572b1e8dd8..7b3ff8f0db53d 100644 --- a/stdlib/LinearAlgebra/src/LinearAlgebra.jl +++ b/stdlib/LinearAlgebra/src/LinearAlgebra.jl @@ -238,14 +238,14 @@ julia> LinearAlgebra.checksquare(A, B) """ function checksquare(A) m,n = size(A) - m == n || throw(DimensionMismatch("matrix is not square: dimensions are $(size(A))")) + m == n || throw(DimensionMismatch(lazy"matrix is not square: dimensions are $(size(A))")) m end function checksquare(A...) sizes = Int[] for a in A - size(a,1)==size(a,2) || throw(DimensionMismatch("matrix is not square: dimensions are $(size(a))")) + size(a,1)==size(a,2) || throw(DimensionMismatch(lazy"matrix is not square: dimensions are $(size(a))")) push!(sizes, size(a,1)) end return sizes diff --git a/stdlib/LinearAlgebra/src/bidiag.jl b/stdlib/LinearAlgebra/src/bidiag.jl index e0280a54f2b82..a5f0af4720cf5 100644 --- a/stdlib/LinearAlgebra/src/bidiag.jl +++ b/stdlib/LinearAlgebra/src/bidiag.jl @@ -165,8 +165,8 @@ end elseif A.uplo == 'L' && (i == j + 1) @inbounds A.ev[j] = x elseif !iszero(x) - throw(ArgumentError(string("cannot set entry ($i, $j) off the ", - "$(istriu(A) ? "upper" : "lower") bidiagonal band to a nonzero value ($x)"))) + throw(ArgumentError(LazyString(lazy"cannot set entry ($i, $j) off the ", + istriu(A) ? "upper" : "lower", " bidiagonal band to a nonzero value ", x))) end return x end @@ -337,8 +337,8 @@ isdiag(M::Bidiagonal) = iszero(M.ev) function tril!(M::Bidiagonal{T}, k::Integer=0) where T n = length(M.dv) if !(-n - 1 <= k <= n - 1) - throw(ArgumentError(string("the requested diagonal, $k, must be at least ", - "$(-n - 1) and at most $(n - 1) in an $n-by-$n matrix"))) + throw(ArgumentError(LazyString(lazy"the requested diagonal, $k, must be at least ", + lazy"$(-n - 1) and at most $(n - 1) in an $n-by-$n matrix"))) elseif M.uplo == 'U' && k < 0 fill!(M.dv, zero(T)) fill!(M.ev, zero(T)) @@ -356,8 +356,8 @@ end function triu!(M::Bidiagonal{T}, k::Integer=0) where T n = length(M.dv) if !(-n + 1 <= k <= n + 1) - throw(ArgumentError(string("the requested diagonal, $k, must be at least", - "$(-n + 1) and at most $(n + 1) in an $n-by-$n matrix"))) + throw(ArgumentError(LazyString(lazy"the requested diagonal, $k, must be at least", + lazy"$(-n + 1) and at most $(n + 1) in an $n-by-$n matrix"))) elseif M.uplo == 'L' && k > 0 fill!(M.dv, zero(T)) fill!(M.ev, zero(T)) @@ -382,8 +382,8 @@ function diag(M::Bidiagonal{T}, n::Integer=0) where T elseif -size(M,1) <= n <= size(M,1) return fill!(similar(M.dv, size(M,1)-abs(n)), zero(T)) else - throw(ArgumentError(string("requested diagonal, $n, must be at least $(-size(M, 1)) ", - "and at most $(size(M, 2)) for an $(size(M, 1))-by-$(size(M, 2)) matrix"))) + throw(ArgumentError(LazyString(lazy"requested diagonal, $n, must be at least $(-size(M, 1)) ", + lazy"and at most $(size(M, 2)) for an $(size(M, 1))-by-$(size(M, 2)) matrix"))) end end diff --git a/stdlib/LinearAlgebra/src/dense.jl b/stdlib/LinearAlgebra/src/dense.jl index b8a44159de8bd..8d5a3e6ea8de2 100644 --- a/stdlib/LinearAlgebra/src/dense.jl +++ b/stdlib/LinearAlgebra/src/dense.jl @@ -1483,10 +1483,10 @@ function pinv(A::AbstractMatrix{T}; atol::Real = 0.0, rtol::Real = (eps(real(flo return B end SVD = svd(A) - tol = max(rtol*maximum(SVD.S), atol) + tol2 = max(rtol*maximum(SVD.S), atol) Stype = eltype(SVD.S) Sinv = fill!(similar(A, Stype, length(SVD.S)), 0) - index = SVD.S .> tol + index = SVD.S .> tol2 Sinv[index] .= pinv.(view(SVD.S, index)) return SVD.Vt' * (Diagonal(Sinv) * SVD.U') end diff --git a/stdlib/LinearAlgebra/src/diagonal.jl b/stdlib/LinearAlgebra/src/diagonal.jl index 29c190e87df72..042a75ffa8630 100644 --- a/stdlib/LinearAlgebra/src/diagonal.jl +++ b/stdlib/LinearAlgebra/src/diagonal.jl @@ -212,8 +212,8 @@ end function tril!(D::Diagonal{T}, k::Integer=0) where T n = size(D,1) if !(-n - 1 <= k <= n - 1) - throw(ArgumentError(string("the requested diagonal, $k, must be at least ", - "$(-n - 1) and at most $(n - 1) in an $n-by-$n matrix"))) + throw(ArgumentError(LazyString(lazy"the requested diagonal, $k, must be at least ", + lazy"$(-n - 1) and at most $(n - 1) in an $n-by-$n matrix"))) elseif k < 0 fill!(D.diag, zero(T)) end diff --git a/stdlib/LinearAlgebra/src/generic.jl b/stdlib/LinearAlgebra/src/generic.jl index 9cbe3f76ccfb9..227b91ebb669f 100644 --- a/stdlib/LinearAlgebra/src/generic.jl +++ b/stdlib/LinearAlgebra/src/generic.jl @@ -1594,7 +1594,7 @@ end """ reflectorApply!(x, τ, A) -Multiplies `A` in-place by a Householder reflection on the left. It is equivalent to `A .= (I - τ*[1; x] * [1; x]')*A`. +Multiplies `A` in-place by a Householder reflection on the left. It is equivalent to `A .= (I - conj(τ)*[1; x[2:end]]*[1; x[2:end]]')*A`. """ @inline function reflectorApply!(x::AbstractVector, τ::Number, A::AbstractVecOrMat) require_one_based_indexing(x) diff --git a/stdlib/LinearAlgebra/src/lapack.jl b/stdlib/LinearAlgebra/src/lapack.jl index 6353f9fa8d266..035028f7512cf 100644 --- a/stdlib/LinearAlgebra/src/lapack.jl +++ b/stdlib/LinearAlgebra/src/lapack.jl @@ -3633,7 +3633,7 @@ for (trcon, trevc, trrfs, elty) in # LOGICAL SELECT( * ) # DOUBLE PRECISION T( LDT, * ), VL( LDVL, * ), VR( LDVR, * ), #$ WORK( * ) - function trevc!(side::AbstractChar, howmny::AbstractChar, select::AbstractVector{BlasInt}, T::AbstractMatrix{$elty}, + Base.@constprop :aggressive function trevc!(side::AbstractChar, howmny::AbstractChar, select::AbstractVector{BlasInt}, T::AbstractMatrix{$elty}, VL::AbstractMatrix{$elty} = similar(T), VR::AbstractMatrix{$elty} = similar(T)) require_one_based_indexing(select, T, VL, VR) diff --git a/stdlib/LinearAlgebra/src/lbt.jl b/stdlib/LinearAlgebra/src/lbt.jl index b133741611adc..909f673740a08 100644 --- a/stdlib/LinearAlgebra/src/lbt.jl +++ b/stdlib/LinearAlgebra/src/lbt.jl @@ -13,6 +13,19 @@ struct lbt_library_info_t f2c::Int32 cblas::Int32 end + +macro get_warn(map, key) + return quote + if !haskey($(esc(map)), $(esc(key))) + @warn(string("[LBT] Unknown key into ", $(string(map)), ": ", $(esc(key)), ", defaulting to :unknown")) + # All the unknown values share a common value: `-1` + $(esc(map))[$(esc(LBT_INTERFACE_UNKNOWN))] + else + $(esc(map))[$(esc(key))] + end + end +end + const LBT_INTERFACE_LP64 = 32 const LBT_INTERFACE_ILP64 = 64 const LBT_INTERFACE_UNKNOWN = -1 @@ -35,10 +48,12 @@ const LBT_INV_F2C_MAP = Dict(v => k for (k, v) in LBT_F2C_MAP) const LBT_COMPLEX_RETSTYLE_NORMAL = 0 const LBT_COMPLEX_RETSTYLE_ARGUMENT = 1 +const LBT_COMPLEX_RETSTYLE_FNDA = 2 const LBT_COMPLEX_RETSTYLE_UNKNOWN = -1 const LBT_COMPLEX_RETSTYLE_MAP = Dict( LBT_COMPLEX_RETSTYLE_NORMAL => :normal, LBT_COMPLEX_RETSTYLE_ARGUMENT => :argument, + LBT_COMPLEX_RETSTYLE_FNDA => :float_normal_double_argument, LBT_COMPLEX_RETSTYLE_UNKNOWN => :unknown, ) const LBT_INV_COMPLEX_RETSTYLE_MAP = Dict(v => k for (k, v) in LBT_COMPLEX_RETSTYLE_MAP) @@ -69,10 +84,10 @@ struct LBTLibraryInfo lib_info.handle, unsafe_string(lib_info.suffix), unsafe_wrap(Vector{UInt8}, lib_info.active_forwards, div(num_exported_symbols,8)+1), - LBT_INTERFACE_MAP[lib_info.interface], - LBT_COMPLEX_RETSTYLE_MAP[lib_info.complex_retstyle], - LBT_F2C_MAP[lib_info.f2c], - LBT_CBLAS_MAP[lib_info.cblas], + @get_warn(LBT_INTERFACE_MAP, lib_info.interface), + @get_warn(LBT_COMPLEX_RETSTYLE_MAP, lib_info.complex_retstyle), + @get_warn(LBT_F2C_MAP, lib_info.f2c), + @get_warn(LBT_CBLAS_MAP, lib_info.cblas), ) end end @@ -269,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/triangular.jl b/stdlib/LinearAlgebra/src/triangular.jl index e8291b1081df2..3e87f6d346e2c 100644 --- a/stdlib/LinearAlgebra/src/triangular.jl +++ b/stdlib/LinearAlgebra/src/triangular.jl @@ -1131,6 +1131,7 @@ function generic_trimatdiv!(C::AbstractVecOrMat, uploc, isunitc, tfun::Function, if size(C) != size(B) throw(DimensionMismatch("size of output, $(size(C)), does not match size of right hand side, $(size(B))")) end + iszero(mA) && return C oA = oneunit(eltype(A)) @inbounds if uploc == 'U' if isunitc == 'N' @@ -1267,6 +1268,7 @@ function generic_trimatdiv!(C::AbstractVecOrMat, uploc, isunitc, ::Function, xA: if size(C) != size(B) throw(DimensionMismatch("size of output, $(size(C)), does not match size of right hand side, $(size(B))")) end + iszero(mA) && return C oA = oneunit(eltype(A)) @inbounds if uploc == 'U' if isunitc == 'N' diff --git a/stdlib/LinearAlgebra/src/tridiag.jl b/stdlib/LinearAlgebra/src/tridiag.jl index 174b368a8615a..1df166311aceb 100644 --- a/stdlib/LinearAlgebra/src/tridiag.jl +++ b/stdlib/LinearAlgebra/src/tridiag.jl @@ -173,7 +173,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) function diag(M::SymTridiagonal{T}, n::Integer=0) where T<:Number # every branch call similar(..., ::Int) to make sure the diff --git a/stdlib/LinearAlgebra/test/adjtrans.jl b/stdlib/LinearAlgebra/test/adjtrans.jl index 2362ec7fb28f2..93d2f264b05fe 100644 --- a/stdlib/LinearAlgebra/test/adjtrans.jl +++ b/stdlib/LinearAlgebra/test/adjtrans.jl @@ -639,7 +639,7 @@ end @testset "trace" begin for T in (Float64, ComplexF64), t in (adjoint, transpose) A = randn(T, 10, 10) - @test tr(t(A)) == tr(copy(t(A))) == t(tr(A)) + @test tr(t(A)) ≈ tr(copy(t(A))) ≈ t(tr(A)) end end diff --git a/stdlib/LinearAlgebra/test/lu.jl b/stdlib/LinearAlgebra/test/lu.jl index 744cc543b993e..1797d8b5a9017 100644 --- a/stdlib/LinearAlgebra/test/lu.jl +++ b/stdlib/LinearAlgebra/test/lu.jl @@ -480,4 +480,17 @@ end LinearAlgebra.generic_lufact!(fill(Inf, 2, 2), check=false) end +@testset "lu for empty matrices" begin + for T in (Float64, BigFloat) + A = fill(T(0.0), 0, 0) + v = fill(T(1.0), 0, 10) + @test A \ v ≈ lu(A) \ v + vt = permutedims(v) + @test vt / A ≈ vt / lu(A) + B = UpperTriangular(transpose(fill(complex(T(0.0)), 0, 0)')) + @test B \ v ≈ v + @test vt / B ≈ vt + end +end + end # module TestLU diff --git a/stdlib/LinearAlgebra/test/symmetric.jl b/stdlib/LinearAlgebra/test/symmetric.jl index f45ca2def04ff..16c83f3ecdf48 100644 --- a/stdlib/LinearAlgebra/test/symmetric.jl +++ b/stdlib/LinearAlgebra/test/symmetric.jl @@ -220,8 +220,8 @@ end @testset "linalg unary ops" begin @testset "tr" begin - @test tr(asym) == tr(Symmetric(asym)) - @test tr(aherm) == tr(Hermitian(aherm)) + @test tr(asym) ≈ tr(Symmetric(asym)) + @test tr(aherm) ≈ tr(Hermitian(aherm)) end @testset "isposdef[!]" begin diff --git a/stdlib/LinearAlgebra/test/triangular.jl b/stdlib/LinearAlgebra/test/triangular.jl index 759f89f6f7220..7be97baa7084a 100644 --- a/stdlib/LinearAlgebra/test/triangular.jl +++ b/stdlib/LinearAlgebra/test/triangular.jl @@ -879,4 +879,10 @@ end @test transpose!(U) == Ut end +@testset "type-stable eigvecs" begin + D = Float64[1 0; 0 2] + V = @inferred eigvecs(UpperTriangular(D)) + @test V == Diagonal([1, 1]) +end + end # module TestTriangular diff --git a/stdlib/LinearAlgebra/test/tridiag.jl b/stdlib/LinearAlgebra/test/tridiag.jl index d4b2dd5e3f269..bb6b2426b68bb 100644 --- a/stdlib/LinearAlgebra/test/tridiag.jl +++ b/stdlib/LinearAlgebra/test/tridiag.jl @@ -459,7 +459,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) @@ -473,6 +473,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 diff --git a/stdlib/Pkg.version b/stdlib/Pkg.version index 2d2683e9e9bb1..709c896f68ca0 100644 --- a/stdlib/Pkg.version +++ b/stdlib/Pkg.version @@ -1,4 +1,4 @@ PKG_BRANCH = release-1.10 -PKG_SHA1 = f487626b090b91493828cbcde30eed96fb9f8e8f +PKG_SHA1 = edfa2ed0ea117d61d33405d4214edb6513b3f236 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 690d0465b3ec0..2a4dc5074ebc3 100644 --- a/stdlib/Profile/src/Profile.jl +++ b/stdlib/Profile/src/Profile.jl @@ -1,7 +1,24 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license """ -Profiling support, main entry point is the [`@profile`](@ref) macro. + Profile + +Profiling support. + +## CPU profiling +- `@profile foo()` to profile a specific call. +- `Profile.print()` to print the report. +- `Profile.clear()` to clear the buffer. +- Send a $(Sys.isbsd() ? "SIGINFO (ctrl-t)" : "SIGUSR1") signal to the process to automatically trigger a profile and print. + +## Memory profiling +- `Profile.Allocs.@profile [sample_rate=0.1] foo()` to sample allocations within a specific call. A sample rate of 1.0 will record everything; 0.0 will record nothing. +- `Profile.Allocs.print()` to print the report. +- `Profile.Allocs.clear()` to clear the buffer. + +## Heap profiling +- `Profile.take_heap_snapshot()` to record a `.heapsnapshot` record of the heap. +- Set `JULIA_PROFILE_PEEK_HEAP_SNAPSHOT=true` to capture a heap snapshot when signal $(Sys.isbsd() ? "SIGINFO (ctrl-t)" : "SIGUSR1") is sent. """ module Profile @@ -475,7 +492,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, @@ -651,7 +668,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/TOML/src/print.jl b/stdlib/TOML/src/print.jl index 1fa9f97405504..af792b72d2dcc 100644 --- a/stdlib/TOML/src/print.jl +++ b/stdlib/TOML/src/print.jl @@ -97,9 +97,10 @@ function printvalue(f::MbyFunc, io::IO, value::TOMLValue) value isa AbstractFloat ? Base.print(io, isnan(value) ? "nan" : isinf(value) ? string(value > 0 ? "+" : "-", "inf") : Float64(value)) : # TOML specifies IEEE 754 binary64 for float - value isa AbstractString ? (Base.print(io, "\""); + value isa AbstractString ? (qmark = Base.contains(value, "\n") ? "\"\"\"" : "\""; + Base.print(io, qmark); print_toml_escaped(io, value); - Base.print(io, "\"")) : + Base.print(io, qmark)) : value isa AbstractDict ? print_inline_table(f, io, value) : error("internal error in TOML printing, unhandled value") end diff --git a/stdlib/TOML/test/print.jl b/stdlib/TOML/test/print.jl index 765b6feb491a5..d5b325ff9b3b6 100644 --- a/stdlib/TOML/test/print.jl +++ b/stdlib/TOML/test/print.jl @@ -140,3 +140,13 @@ d = "hello" a = 2 b = 9.9 """ + +# multiline strings (#55083) +s = """ +a = \"\"\"lorem ipsum + + + +alpha\"\"\" +""" +@test roundtrip(s) diff --git a/stdlib/libblastrampoline_jll/Project.toml b/stdlib/libblastrampoline_jll/Project.toml index 6ee704bc7e1c4..fef963a88f5fd 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.8.0+1" +version = "5.11.0+0" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" diff --git a/sysimage.mk b/sysimage.mk index 0d2c9aff126e4..fa7d46cc81fb0 100644 --- a/sysimage.mk +++ b/sysimage.mk @@ -16,7 +16,7 @@ $(build_private_libdir)/%.$(SHLIB_EXT): $(build_private_libdir)/%-o.a @$(call PRINT_LINK, $(CXX) $(LDFLAGS) -shared $(fPIC) -L$(build_private_libdir) -L$(build_libdir) -L$(build_shlibdir) -o $@ \ $(WHOLE_ARCHIVE) $< $(NO_WHOLE_ARCHIVE) \ $(if $(findstring -debug,$(notdir $@)),-ljulia-internal-debug -ljulia-debug,-ljulia-internal -ljulia) \ - $$([ $(OS) = WINNT ] && echo '' -lssp --disable-auto-import --disable-runtime-pseudo-reloc)) + $$([ $(OS) = WINNT ] && echo '' $(LIBM) -lssp --disable-auto-import --disable-runtime-pseudo-reloc)) @$(INSTALL_NAME_CMD)$(notdir $@) $@ @$(DSYMUTIL) $@ diff --git a/test/abstractarray.jl b/test/abstractarray.jl index 9691db88b6e99..8d0c83897611b 100644 --- a/test/abstractarray.jl +++ b/test/abstractarray.jl @@ -1684,6 +1684,9 @@ end @test_throws ArgumentError stack([1:3, 4:6]; dims=3) @test_throws ArgumentError stack(abs2, 1:3; dims=2) + @test stack(["hello", "world"]) isa Matrix{Char} + @test_throws DimensionMismatch stack(["hello", "world!"]) # had a bug in error printing + # Empty @test_throws ArgumentError stack(()) @test_throws ArgumentError stack([]) diff --git a/test/compiler/codegen.jl b/test/compiler/codegen.jl index 88f9948bb30a5..f7df1be04f18d 100644 --- a/test/compiler/codegen.jl +++ b/test/compiler/codegen.jl @@ -852,3 +852,21 @@ end # https://github.com/JuliaLang/julia/issues/51233 obj51233 = (1,) @test_throws ErrorException obj51233.x + +bar54599() = Base.inferencebarrier(true) ? (Base.PkgId(Main),1) : nothing + +function foo54599() + pkginfo = @noinline bar54599() + pkgid = pkginfo !== nothing ? pkginfo[1] : nothing + @noinline println(devnull, pkgid) + pkgid.uuid !== nothing ? pkgid.uuid : false +end + +#this function used to crash allocopt due to a no predecessors bug +barnopreds() = Base.inferencebarrier(true) ? (Base.PkgId(Test),1) : nothing +function foonopreds() + pkginfo = @noinline barnopreds() + pkgid = pkginfo !== nothing ? pkginfo[1] : nothing + pkgid.uuid !== nothing ? pkgid.uuid : false +end +@test foonopreds() !== nothing diff --git a/test/gc.jl b/test/gc.jl index e085c1d8658e5..eedc7e27d1f4f 100644 --- a/test/gc.jl +++ b/test/gc.jl @@ -5,11 +5,13 @@ using Test function run_gctest(file) let cmd = `$(Base.julia_cmd()) --depwarn=error --rr-detach --startup-file=no $file` @testset for test_nthreads in (1, 2, 4) - @testset for concurrent_sweep in (0, 1) - new_env = copy(ENV) - new_env["JULIA_NUM_THREADS"] = string(test_nthreads) - new_env["JULIA_NUM_GC_THREADS"] = "$(test_nthreads),$(concurrent_sweep)" - @test success(run(pipeline(setenv(cmd, new_env), stdout = stdout, stderr = stderr))) + @testset for test_nithreads in (0, 1) + @testset for concurrent_sweep in (0, 1) + new_env = copy(ENV) + new_env["JULIA_NUM_THREADS"] = "$test_nthreads,$test_nithreads" + new_env["JULIA_NUM_GC_THREADS"] = "$(test_nthreads),$(concurrent_sweep)" + @test success(run(pipeline(setenv(cmd, new_env), stdout = stdout, stderr = stderr))) + end end end end diff --git a/test/llvmpasses/alloc-opt-bits.ll b/test/llvmpasses/alloc-opt-bits.ll new file mode 100644 index 0000000000000..6159ae1f8ebb3 --- /dev/null +++ b/test/llvmpasses/alloc-opt-bits.ll @@ -0,0 +1,41 @@ +; This file is a part of Julia. License is MIT: https://julialang.org/license + + +; RUN: opt -enable-new-pm=0 --opaque-pointers=0 -load libjulia-codegen%shlibext -AllocOpt -S %s | FileCheck %s --check-prefixes=CHECK,TYPED +; RUN: opt -enable-new-pm=1 --opaque-pointers=0 --load-pass-plugin=libjulia-codegen%shlibext -passes='function(AllocOpt)' -S %s | FileCheck %s --check-prefixes=CHECK,TYPED + +; RUN: opt -enable-new-pm=0 --opaque-pointers=1 -load libjulia-codegen%shlibext -AllocOpt -S %s | FileCheck %s --check-prefixes=CHECK,OPAQUE +; RUN: opt -enable-new-pm=1 --opaque-pointers=1 --load-pass-plugin=libjulia-codegen%shlibext -passes='function(AllocOpt)' -S %s | FileCheck %s --check-prefixes=CHECK,OPAQUE + + +@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 +; OPAQUE: call noalias ptr addrspace(10) @julia.gc_alloc_obj +; TYPED: call noalias {} addrspace(10)* @julia.gc_alloc_obj + +define void @ptr_and_bits(i8* %fptr, i1 %b, i1 %b2, i32 %idx) { + %pgcstack = call {}*** @julia.get_pgcstack() + %gcstack = bitcast {}*** %pgcstack to {}** + %current_task = getelementptr inbounds {}*, {}** %gcstack, i64 -12 + %v = call noalias {} addrspace(10)* @julia.gc_alloc_obj({}** %current_task, i64 16, {} addrspace(10)* @tag) + %v2 = bitcast {} addrspace(10)* %v to { i64, {} addrspace(10)* } addrspace(10)* + %g0 = getelementptr { i64, {} addrspace(10)* }, { i64, {} addrspace(10)* } addrspace(10)* %v2, i32 %idx, i32 1 + store {} addrspace(10)* @glob, {} addrspace(10)* addrspace(10)* %g0 + + %g1 = getelementptr { i64, {} addrspace(10)* }, { i64, {} addrspace(10)* } addrspace(10)* %v2, i32 %idx, i32 0 + store i64 7, i64 addrspace(10)* %g1 + + %res = load {} addrspace(10)*, {} addrspace(10)* addrspace(10)* %g0 + %res2 = load i64, i64 addrspace(10)* %g1 + ret void +} + +declare noalias {} addrspace(10)* @julia.gc_alloc_obj({}**, i64, {} addrspace(10)*) + +declare {}*** @julia.get_pgcstack() diff --git a/test/llvmpasses/alloc-opt-pass.ll b/test/llvmpasses/alloc-opt-pass.ll index b7e0647263caa..81a1f5dd2300b 100644 --- a/test/llvmpasses/alloc-opt-pass.ll +++ b/test/llvmpasses/alloc-opt-pass.ll @@ -1,8 +1,5 @@ ; This file is a part of Julia. License is MIT: https://julialang.org/license -; RUN: opt -enable-new-pm=0 --opaque-pointers=0 -load libjulia-codegen%shlibext -AllocOpt -S %s | FileCheck %s --check-prefixes=CHECK,TYPED -; RUN: opt -enable-new-pm=1 --opaque-pointers=0 --load-pass-plugin=libjulia-codegen%shlibext -passes='function(AllocOpt)' -S %s | FileCheck %s --check-prefixes=CHECK,TYPED - ; RUN: opt -enable-new-pm=0 --opaque-pointers=1 -load libjulia-codegen%shlibext -AllocOpt -S %s | FileCheck %s --check-prefixes=CHECK,OPAQUE ; RUN: opt -enable-new-pm=1 --opaque-pointers=1 --load-pass-plugin=libjulia-codegen%shlibext -passes='function(AllocOpt)' -S %s | FileCheck %s --check-prefixes=CHECK,OPAQUE @@ -23,23 +20,23 @@ ; CHECK-NEXT: br label %L3 ; CHECK: L3: -define void @preserve_branches(i8* %fptr, i1 %b, i1 %b2) { - %pgcstack = call {}*** @julia.get_pgcstack() - %ptls = call {}*** @julia.ptls_states() - %ptls_i8 = bitcast {}*** %ptls to i8* +define void @preserve_branches(ptr %fptr, i1 %b, i1 %b2) { + %pgcstack = call ptr @julia.get_pgcstack() + %ptls = call ptr @julia.ptls_states() + %ptls_i8 = bitcast ptr %ptls to ptr br i1 %b, label %L1, label %L3 -L1: - %v = call noalias {} addrspace(10)* @julia.gc_alloc_obj(i8* %ptls_i8, i64 8, {} addrspace(10)* @tag) - %tok = call token (...) @llvm.julia.gc_preserve_begin({} addrspace(10)* nonnull %v) +L1: ; preds = %0 + %v = call noalias ptr addrspace(10) @julia.gc_alloc_obj(ptr %ptls_i8, i64 8, ptr addrspace(10) @tag) + %tok = call token (...) @llvm.julia.gc_preserve_begin(ptr addrspace(10) nonnull %v) call void @external_function() br i1 %b2, label %L2, label %L3 -L2: +L2: ; preds = %L1 call void @external_function() br label %L3 -L3: +L3: ; preds = %L2, %L1, %0 ret void } ; CHECK-LABEL: }{{$}} @@ -58,24 +55,24 @@ L3: ; CHECK-NEXT: br label %L3 ; CHECK: L3: -define void @preserve_branches2(i8* %fptr, i1 %b, i1 %b2) { - %pgcstack = call {}*** @julia.get_pgcstack() - %ptls = call {}*** @julia.ptls_states() - %ptls_i8 = bitcast {}*** %ptls to i8* - %v2 = call {} addrspace(10)* @external_function2() +define void @preserve_branches2(ptr %fptr, i1 %b, i1 %b2) { + %pgcstack = call ptr @julia.get_pgcstack() + %ptls = call ptr @julia.ptls_states() + %ptls_i8 = bitcast ptr %ptls to ptr + %v2 = call ptr addrspace(10) @external_function2() br i1 %b, label %L1, label %L3 -L1: - %v = call noalias {} addrspace(10)* @julia.gc_alloc_obj(i8* %ptls_i8, i64 8, {} addrspace(10)* @tag) - %tok = call token (...) @llvm.julia.gc_preserve_begin({} addrspace(10)* %v, {} addrspace(10)* nonnull %v2) +L1: ; preds = %0 + %v = call noalias ptr addrspace(10) @julia.gc_alloc_obj(ptr %ptls_i8, i64 8, ptr addrspace(10) @tag) + %tok = call token (...) @llvm.julia.gc_preserve_begin(ptr addrspace(10) %v, ptr addrspace(10) nonnull %v2) call void @external_function() br i1 %b2, label %L2, label %L3 -L2: +L2: ; preds = %L1 call void @external_function() br label %L3 -L3: +L3: ; preds = %L2, %L1, %0 ret void } ; CHECK-LABEL: }{{$}} @@ -85,26 +82,30 @@ L3: ; CHECK-NOT: alloca i96 ; CHECK: ret void define void @legal_int_types() { - %pgcstack = call {}*** @julia.get_pgcstack() - %ptls = call {}*** @julia.ptls_states() - %ptls_i8 = bitcast {}*** %ptls to i8* - %var1 = call {} addrspace(10)* @julia.gc_alloc_obj(i8* %ptls_i8, i64 12, {} addrspace(10)* @tag) - %var2 = addrspacecast {} addrspace(10)* %var1 to {} addrspace(11)* - %var3 = call {}* @julia.pointer_from_objref({} addrspace(11)* %var2) + %pgcstack = call ptr @julia.get_pgcstack() + %ptls = call ptr @julia.ptls_states() + %ptls_i8 = bitcast ptr %ptls to ptr + %var1 = call ptr addrspace(10) @julia.gc_alloc_obj(ptr %ptls_i8, i64 12, ptr addrspace(10) @tag) + %var2 = addrspacecast ptr addrspace(10) %var1 to ptr addrspace(11) + %var3 = call ptr @julia.pointer_from_objref(ptr addrspace(11) %var2) ret void } ; CHECK-LABEL: }{{$}} - declare void @external_function() -declare {} addrspace(10)* @external_function2() -declare {}*** @julia.ptls_states() -declare {}*** @julia.get_pgcstack() -declare noalias {} addrspace(10)* @julia.gc_alloc_obj(i8*, i64, {} addrspace(10)*) -declare {}* @julia.pointer_from_objref({} addrspace(11)*) -declare void @llvm.memcpy.p11i8.p0i8.i64(i8 addrspace(11)* nocapture writeonly, i8* nocapture readonly, i64, i32, i1) -declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i1) + +declare ptr addrspace(10) @external_function2() + +declare ptr @julia.ptls_states() + +declare ptr @julia.get_pgcstack() + +declare noalias ptr addrspace(10) @julia.gc_alloc_obj(ptr, i64, ptr addrspace(10)) + +declare ptr @julia.pointer_from_objref(ptr addrspace(11)) + declare token @llvm.julia.gc_preserve_begin(...) + declare void @llvm.julia.gc_preserve_end(token) ; CHECK-LABEL: @memref_collision @@ -121,24 +122,25 @@ declare void @llvm.julia.gc_preserve_end(token) ; CHECK: L2: ; CHECK: load i define void @memref_collision(i64 %x) { - %pgcstack = call {}*** @julia.get_pgcstack() - %ptls = call {}*** @julia.ptls_states() - %ptls_i8 = bitcast {}*** %ptls to i8* - %v = call noalias {} addrspace(10)* @julia.gc_alloc_obj(i8* %ptls_i8, i64 8, {} addrspace(10)* @tag) - %v_p = bitcast {} addrspace(10)* %v to i64 addrspace(10)* - store i64 %x, i64 addrspace(10)* %v_p - br i1 0, label %L1, label %L2 - -L1: - %v1 = bitcast {} addrspace(10)* %v to {} addrspace(10)* addrspace(10)* - %v1_x = load {} addrspace(10)*, {} addrspace(10)* addrspace(10)* %v1 + %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 8, ptr addrspace(10) @tag) + %v_p = bitcast ptr addrspace(10) %v to ptr addrspace(10) + store i64 %x, ptr addrspace(10) %v_p, align 4 + br i1 false, label %L1, label %L2 + +L1: ; preds = %0 + %v1 = bitcast ptr addrspace(10) %v to ptr addrspace(10) + %v1_x = load ptr addrspace(10), ptr addrspace(10) %v1, align 8 ret void -L2: - %v2 = bitcast {} addrspace(10)* %v to i64 addrspace(10)* - %v2_x = load i64, i64 addrspace(10)* %v2 +L2: ; preds = %0 + %v2 = bitcast ptr addrspace(10) %v to ptr addrspace(10) + %v2_x = load i64, ptr addrspace(10) %v2, align 4 ret void } + ; CHECK-LABEL: }{{$}} ; CHECK-LABEL: @lifetime_no_preserve_end @@ -146,19 +148,50 @@ L2: ; CHECK-NOT: call token(...) @llvm.julia.gc_preserve_begin ; CHECK: call void @llvm.lifetime.start ; CHECK-NOT: call void @llvm.lifetime.end -define void @lifetime_no_preserve_end({}* noalias nocapture noundef nonnull sret({}) %0) { - %pgcstack = call {}*** @julia.get_pgcstack() - %ptls = call {}*** @julia.ptls_states() - %ptls_i8 = bitcast {}*** %ptls to i8* - %v = call noalias {} addrspace(10)* @julia.gc_alloc_obj(i8* %ptls_i8, i64 8, {} addrspace(10)* @tag) - %token = call token (...) @llvm.julia.gc_preserve_begin({} addrspace(10)* %v) - %v_derived = addrspacecast {} addrspace(10)* %v to {} addrspace(11)* - %ptr = call nonnull {}* @julia.pointer_from_objref({} addrspace(11)* %v_derived) - %ptr_raw = bitcast {}* %ptr to i8* - call void @external_function() ; safepoint - %ret_raw = bitcast {}* %0 to i8* - call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %ret_raw, i8 * align 8 %ptr_raw, i64 0, i1 false) - %ret_raw2 = bitcast {}* %0 to i8* +define void @lifetime_no_preserve_end(ptr noalias nocapture noundef nonnull sret({}) %0) { + %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 8, ptr addrspace(10) @tag) + %token = call token (...) @llvm.julia.gc_preserve_begin(ptr addrspace(10) %v) + %v_derived = addrspacecast ptr addrspace(10) %v to ptr addrspace(11) + %ptr = call nonnull ptr @julia.pointer_from_objref(ptr addrspace(11) %v_derived) + %ptr_raw = bitcast ptr %ptr to ptr + call void @external_function() + %ret_raw = bitcast ptr %0 to ptr + call void @llvm.memcpy.p0.p0.i64(ptr align 8 %ret_raw, ptr align 8 %ptr_raw, i64 0, i1 false) + %ret_raw2 = bitcast ptr %0 to ptr ret void } ; CHECK-LABEL: }{{$}} + +; Test that the pass handles dead basic blocks with references to the allocation +; CHECK-LABEL: @nopreds +; CHECK: alloca i8, i64 0, align 1 +; CHECK: call void @llvm.lifetime.start +define swiftcc { ptr addrspace(10), i8 } @nopreds() { +top: + %0 = call ptr addrspace(10) @julia.gc_alloc_obj(ptr null, i64 0, ptr addrspace(10) null) + %1 = addrspacecast ptr addrspace(10) %0 to ptr addrspace(11) + br label %common.ret + +common.ret: ; preds = %union_move9, %top + ret { ptr addrspace(10), i8 } zeroinitializer + +union_move9: ; No predecessors! + call void @llvm.memcpy.p0.p11.i64(ptr null, ptr addrspace(11) %1, i64 0, i1 false) + br label %common.ret +} +; CHECK-LABEL: }{{$}} + +; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite) +declare void @llvm.memcpy.p11.p0.i64(ptr addrspace(11) noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #0 +; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite) +declare void @llvm.memcpy.p0.p11.i64(ptr noalias nocapture writeonly, ptr addrspace(11) noalias nocapture readonly, i64, i1 immarg) #0 +; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite) +declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #0 + +attributes #0 = { nocallback nofree nounwind willreturn } +attributes #1 = { allockind("alloc") } +attributes #2 = { allockind("alloc,uninitialized") } +attributes #3 = { allockind("alloc,zeroed") } diff --git a/test/llvmpasses/final-lower-gc.ll b/test/llvmpasses/final-lower-gc.ll index 5bbaa2f4d81ea..b109abe769782 100644 --- a/test/llvmpasses/final-lower-gc.ll +++ b/test/llvmpasses/final-lower-gc.ll @@ -95,9 +95,8 @@ top: %pgcstack = call {}*** @julia.get_pgcstack() %ptls = call {}*** @julia.ptls_states() %ptls_i8 = bitcast {}*** %ptls to i8* -; CHECK: %0 = add i64 %size, 8 -; TYPED: %v = call noalias nonnull dereferenceable(8) {} addrspace(10)* @ijl_gc_alloc_typed(i8* %ptls_i8, i64 %0, i8* null) -; OPAQUE: %v = call noalias nonnull dereferenceable(8) ptr addrspace(10) @ijl_gc_alloc_typed(ptr %ptls_i8, i64 %0, ptr null) +; TYPED: %v = call noalias nonnull dereferenceable(8) {} addrspace(10)* @ijl_gc_alloc_typed(i8* %ptls_i8, i64 %size, i8* null) +; OPAQUE: %v = call noalias nonnull dereferenceable(8) ptr addrspace(10) @ijl_gc_alloc_typed(ptr %ptls_i8, i64 %size, ptr null) %v = call {} addrspace(10)* @julia.gc_alloc_bytes(i8* %ptls_i8, i64 %size) %0 = bitcast {} addrspace(10)* %v to {} addrspace(10)* addrspace(10)* %1 = getelementptr {} addrspace(10)*, {} addrspace(10)* addrspace(10)* %0, i64 -1 diff --git a/test/precompile.jl b/test/precompile.jl index d317731b51370..0b9cc9eab3417 100644 --- a/test/precompile.jl +++ b/test/precompile.jl @@ -522,6 +522,10 @@ precompile_test_harness(false) do dir @eval using Baz @test Base.invokelatest(Baz.baz) == 1 + # 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/reinterpretarray.jl b/test/reinterpretarray.jl index 501e9f4a9b57f..cda0d61ddb05f 100644 --- a/test/reinterpretarray.jl +++ b/test/reinterpretarray.jl @@ -32,9 +32,8 @@ end @test_throws ArgumentError("cannot reinterpret `Vector{Int32}` as `Int32`, type `Vector{Int32}` is not a bits type") reinterpret(Int32, Av) @test_throws ArgumentError("cannot reinterpret a zero-dimensional `Int64` array to `Int32` which is of a different size") reinterpret(Int32, reshape([Int64(0)])) @test_throws ArgumentError("cannot reinterpret a zero-dimensional `Int32` array to `Int64` which is of a different size") reinterpret(Int64, reshape([Int32(0)])) -@test_throws ArgumentError("""cannot reinterpret an `$Int` array to `Tuple{$Int, $Int}` whose first dimension has size `5`. - The resulting array would have non-integral first dimension. - """) reinterpret(Tuple{Int,Int}, [1,2,3,4,5]) +@test_throws ArgumentError("cannot reinterpret an `$Int` array to `Tuple{$Int, $Int}` whose first dimension has size `5`."* + " The resulting array would have a non-integral first dimension.") reinterpret(Tuple{Int,Int}, [1,2,3,4,5]) @test_throws ArgumentError("`reinterpret(reshape, Complex{Int64}, a)` where `eltype(a)` is Int64 requires that `axes(a, 1)` (got Base.OneTo(4)) be equal to 1:2 (from the ratio of element sizes)") reinterpret(reshape, Complex{Int64}, A) @test_throws ArgumentError("`reinterpret(reshape, T, a)` requires that one of `sizeof(T)` (got 24) and `sizeof(eltype(a))` (got 16) be an integer multiple of the other") reinterpret(reshape, NTuple{3, Int64}, B) diff --git a/test/subarray.jl b/test/subarray.jl index 11d18185dd753..7bd47cac0bb64 100644 --- a/test/subarray.jl +++ b/test/subarray.jl @@ -779,3 +779,34 @@ end @test parent(@inferred(view(A, :, 3, 1, CartesianIndices(()), 1))) === A @test_throws BoundsError view(A, :, 3, 2, CartesianIndices(()), 1) end + +@testset "aliasing checks with shared indices" begin + indices = [1,3] + a = rand(3) + av = @view a[indices] + b = rand(3) + bv = @view b[indices] + @test !Base.mightalias(av, bv) + @test Base.mightalias(a, av) + @test Base.mightalias(b, bv) + @test Base.mightalias(indices, av) + @test Base.mightalias(indices, bv) + @test Base.mightalias(view(indices, :), av) + @test Base.mightalias(view(indices, :), bv) +end + +@testset "aliasing checks with disjoint arrays" begin + A = rand(3,4,5) + @test Base.mightalias(view(A, :, :, 1), view(A, :, :, 1)) + @test !Base.mightalias(view(A, :, :, 1), view(A, :, :, 2)) + + B = reinterpret(UInt64, A) + @test Base.mightalias(view(B, :, :, 1), view(A, :, :, 1)) + @test !Base.mightalias(view(B, :, :, 1), view(A, :, :, 2)) + + C = reinterpret(UInt32, A) + @test Base.mightalias(view(C, :, :, 1), view(A, :, :, 1)) + @test Base.mightalias(view(C, :, :, 1), view(A, :, :, 2)) # This is overly conservative + @test Base.mightalias(@view(C[begin:2:end, :, 1]), view(A, :, :, 1)) + @test Base.mightalias(@view(C[begin:2:end, :, 1]), view(A, :, :, 2)) # This is overly conservative +end