From c49f4aaee97883bd8fa65ab133870a6fb698ad17 Mon Sep 17 00:00:00 2001 From: Matt Bauman Date: Fri, 26 Jul 2024 11:57:52 -0400 Subject: [PATCH 001/115] == docs: strengthen link between hashing and equality (#55135) ref #55134. --- base/operators.jl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/base/operators.jl b/base/operators.jl index 4a9daf21c4be5..dc3c01e5645cc 100644 --- a/base/operators.jl +++ b/base/operators.jl @@ -111,9 +111,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. From cdd599c320db051005d9581fc09ba6da0693c7f5 Mon Sep 17 00:00:00 2001 From: Diogo Netto <61364108+d-netto@users.noreply.github.com> Date: Fri, 26 Jul 2024 18:00:14 -0300 Subject: [PATCH 002/115] split a lock currently used for symtab + GC pages + perm alloc (#55257) Seems fairly odd to have a single lock protecting the symbol table, GC pages and the permanent allocator -- three parts of the codebase which have little interconnection. Let's create a lock for each. --- src/gc-pages.c | 12 +++++++----- src/gc.c | 3 ++- src/gc.h | 2 ++ src/init.c | 3 +++ src/julia_internal.h | 4 +--- src/symbol.c | 9 +++++---- 6 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/gc-pages.c b/src/gc-pages.c index 698cf84c3cfb6..971dbe92d7fac 100644 --- a/src/gc-pages.c +++ b/src/gc-pages.c @@ -9,6 +9,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 +69,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 +89,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 +129,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 +151,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.c b/src/gc.c index 9f57bf3c6b944..3ab0aa4b1bf1b 100644 --- a/src/gc.c +++ b/src/gc.c @@ -3979,6 +3979,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); @@ -4244,7 +4245,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); diff --git a/src/gc.h b/src/gc.h index e22ded0ec6740..0d8421912dbc7 100644 --- a/src/gc.h +++ b/src/gc.h @@ -574,6 +574,7 @@ 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; @@ -593,6 +594,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/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/julia_internal.h b/src/julia_internal.h index 22c5cdb9a445f..392fe8fd9a1fb 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -350,9 +350,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); @@ -1699,6 +1696,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/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; } From 8a7e23d29b19ebf5755b7c448731360f239dee9a Mon Sep 17 00:00:00 2001 From: Alex Arslan Date: Fri, 26 Jul 2024 20:03:53 -0700 Subject: [PATCH 003/115] Make `jl_*affinity` tests more portable (#55261) Changes made: - Use 0 for the thread ID to ensure it's always valid. The function expects `0 <= tid < jl_n_threads` so 1 is incorrect if `jl_n_threads` is 1. - After retrieving the affinity mask with `jl_getaffinity`, pass that same mask back to `jl_setaffinity`. This ensures that the mask is always valid. Using a mask of all ones results in `EINVAL` on FreeBSD. Based on the discussion in #53402, this change may also fix Windows, so I've tried reenabling it here. - To check whether `jl_getaffinity` actually did something, we can check that the mask is no longer all zeros after the call. Fixes #54817 --- test/threads.jl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) 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 From 9d112fb40000bc7b3a70b39f83edcc12fe95e117 Mon Sep 17 00:00:00 2001 From: Zentrik Date: Sat, 27 Jul 2024 16:25:14 +0100 Subject: [PATCH 004/115] Update download_cmake.sh to cmake 3.30.1 (#55275) --- contrib/download_cmake.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) 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;; From 197295c84aab217bffde01a4339f1d0e8e95fb98 Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Sun, 28 Jul 2024 17:35:28 +0530 Subject: [PATCH 005/115] Restrict binary ops for Diagonal and Symmetric to Number eltypes (#55251) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `(::Diagonal) + (::Symmetric)` and analogous methods were specialized in https://github.com/JuliaLang/julia/pull/35333 to return a `Symmetric`, but these only work if the `Diagonal` is also symmetric. This typically holds for arrays of numbers, but may not hold for block-diagonal and other types for which symmetry isn't guaranteed. This PR restricts the methods to arrays of `Number`s. Fixes, e.g.: ```julia julia> using StaticArrays, LinearAlgebra julia> D = Diagonal(fill(SMatrix{2,2}(1:4), 2)) 2×2 Diagonal{SMatrix{2, 2, Int64, 4}, Vector{SMatrix{2, 2, Int64, 4}}}: [1 3; 2 4] ⋅ ⋅ [1 3; 2 4] julia> S = Symmetric(D) 2×2 Symmetric{AbstractMatrix, Diagonal{SMatrix{2, 2, Int64, 4}, Vector{SMatrix{2, 2, Int64, 4}}}}: [1 3; 3 4] ⋅ ⋅ [1 3; 3 4] julia> S + D 2×2 Symmetric{AbstractMatrix, Diagonal{SMatrix{2, 2, Int64, 4}, Vector{SMatrix{2, 2, Int64, 4}}}}: [2 6; 6 8] ⋅ ⋅ [2 6; 6 8] julia> S[1,1] + D[1,1] 2×2 SMatrix{2, 2, Int64, 4} with indices SOneTo(2)×SOneTo(2): 2 6 5 8 julia> (S + D)[1,1] == S[1,1] + D[1,1] false ``` After this, ```julia julia> S + D 2×2 Matrix{AbstractMatrix{Int64}}: [2 6; 5 8] [0 0; 0 0] [0 0; 0 0] [2 6; 5 8] ``` Even with `Number`s as elements, there might be an issue with `NaN`s along the diagonal as `!issymmetric(NaN)`, but that may be a different PR. --- stdlib/LinearAlgebra/src/diagonal.jl | 4 ++-- stdlib/LinearAlgebra/test/diagonal.jl | 12 ++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/stdlib/LinearAlgebra/src/diagonal.jl b/stdlib/LinearAlgebra/src/diagonal.jl index b3826a2aa7f82..ff8350d8ddeb1 100644 --- a/stdlib/LinearAlgebra/src/diagonal.jl +++ b/stdlib/LinearAlgebra/src/diagonal.jl @@ -268,10 +268,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) diff --git a/stdlib/LinearAlgebra/test/diagonal.jl b/stdlib/LinearAlgebra/test/diagonal.jl index 1a3b8d4fd0ea7..e1fc9afa5ad2e 100644 --- a/stdlib/LinearAlgebra/test/diagonal.jl +++ b/stdlib/LinearAlgebra/test/diagonal.jl @@ -1335,4 +1335,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 From 7de15ba07178c02560ecbfebda98bc811758dd6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mos=C3=A8=20Giordano?= Date: Sun, 28 Jul 2024 20:59:57 +0100 Subject: [PATCH 006/115] [CI] Run whitespace check on GitHub Actions and annotate source code (#55281) There some advantages in running this on GitHub Actions (GHA) rather than Buildkite (BK): * on GHA this task takes ~10 seconds, on BK it takes ~1 minute (job setup on BK takes way too long) * since for this task we can use GitHub-hosted runners (which come with Julia preinstalled), we can spare BK runners from running this job. Admittedly it's very marginal saving, but better than nothing when the queue gets long * using GHA allows us to easily add source code annotations in PR overviews, which make it easier to quickly spot the line to fix from the GitHub web interface. This would be doable also on BK, but slightly more annoying. As [an example](https://github.com/giordano/julia/commit/a7725e47e245fcefd60ed02a2e492ed5a0af13e9): ![image](https://github.com/user-attachments/assets/8a459a61-8953-4590-980e-ff156a62701f) If this PR is accepted, I'll remove the corresponding job from BK. --------- Co-authored-by: Dilum Aluthge --- .github/workflows/Whitespace.yml | 23 +++++++++++++++++++++++ contrib/check-whitespace.jl | 8 ++++++++ 2 files changed, 31 insertions(+) create mode 100644 .github/workflows/Whitespace.yml 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/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) From 079b69e124e5cb3756b190c7b2853deb7c6d1955 Mon Sep 17 00:00:00 2001 From: Dilum Aluthge Date: Sun, 28 Jul 2024 17:26:41 -0400 Subject: [PATCH 007/115] CI: Use Dependabot to update GitHub Actions in this repo, and pin all external GitHub Actions to full-length commit hashes (#55283) --- .github/dependabot.yml | 11 +++++++++++ .github/workflows/LabelCheck.yml | 2 +- .github/workflows/Typos.yml | 4 ++-- .github/workflows/cffconvert.yml | 4 ++-- 4 files changed, 16 insertions(+), 5 deletions(-) create mode 100644 .github/dependabot.yml 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/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" From 5da94687084f46d7b7366aa55b0c75dcc6d5157f Mon Sep 17 00:00:00 2001 From: "Steven G. Johnson" Date: Mon, 29 Jul 2024 00:07:43 -0400 Subject: [PATCH 008/115] use iszero in isinteger(::AbstractFloat) (#55276) This is a very slight tweak to the implementation of `isinteger(::AbstractFloat)` to use `iszero` rather than `== 0`. It shouldn't make any difference with any of the built-in floating-point types, but `iszero` might conceivably be faster for some user-defined types. I also added a comment to indicate why it's using `iszero(x - trunc(x))` rather than `x == trunc(x)` (due to non-finite values); this code dates back to #14569 in Julia 0.5. --------- Co-authored-by: Sukera <11753998+Seelengrab@users.noreply.github.com> --- base/floatfuncs.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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. From 4dfce5d5a5efcb87ebe92b2c8e943a0870c2eae9 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Mon, 29 Jul 2024 14:47:33 +0900 Subject: [PATCH 009/115] adjust the name and remarks of const prop heuristics (#55260) `const_prop_entry_heuristics` currently checks the return type only, so I have given it a name that reflects this and adjusted the remarks accordingly. There are no changes to the basic behavior of inference. --- base/compiler/abstractinterpretation.jl | 27 +++++++++++++------------ test/compiler/inference.jl | 8 ++++---- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index 88c3324668869..3b658534b5d35 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -1034,12 +1034,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 +1061,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 +1091,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 diff --git a/test/compiler/inference.jl b/test/compiler/inference.jl index 2c149b1abf21d..8b6da828af54d 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...)) From 427824ef4189c8d8a6dbad266a7e1d7f2a71eafc Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Tue, 30 Jul 2024 02:02:58 +0900 Subject: [PATCH 010/115] refactoring on SROA passes (#55262) All changes are cosmetic and do not change the basic functionality: - Added the interface type to the callbacks received by `simple_walker` to clarify which objects are passed as callbacks to `simple_walker`. - Replaced ambiguous names like `idx` with more descriptive ones like `defidx` to make the algorithm easier to understand. --- base/compiler/ssair/passes.jl | 157 +++++++++++++++++++--------------- 1 file changed, 88 insertions(+), 69 deletions(-) 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 From 1119f125094c3b944ba728dd73788941050620e8 Mon Sep 17 00:00:00 2001 From: Zentrik Date: Mon, 29 Jul 2024 20:03:17 +0100 Subject: [PATCH 011/115] Revert "Deps: after configuring CMake project, use `cmake --build`, not `make` (#54538)" (#55285) Fixes #55284. --- deps/ittapi.mk | 2 +- deps/libgit2.mk | 4 ++-- deps/libssh2.mk | 4 ++-- deps/libsuitesparse.mk | 6 +++--- deps/libtracyclient.mk | 4 +++- deps/llvm.mk | 4 +++- deps/mbedtls.mk | 4 ++-- deps/unwind.mk | 2 +- deps/zlib.mk | 2 +- 9 files changed, 18 insertions(+), 14 deletions(-) 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..d840a7b298e17 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 > $@ 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/llvm.mk b/deps/llvm.mk index 5e73c18f53289..eddf9b60e38c7 100644 --- a/deps/llvm.mk +++ b/deps/llvm.mk @@ -270,7 +270,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/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/unwind.mk b/deps/unwind.mk index 0bfaca574f5e6..501ea6b8aedcc 100644 --- a/deps/unwind.mk +++ b/deps/unwind.mk @@ -121,7 +121,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, \ From 34cd6103aa68bf07766cdccdc284940091692fe5 Mon Sep 17 00:00:00 2001 From: N5N3 <2642243996@qq.com> Date: Tue, 30 Jul 2024 05:08:28 +0800 Subject: [PATCH 012/115] specificity: ensure fast-path in `sub/eq_msp` handle missing `UnionAll` wrapper correctly. (#54736) --- src/subtype.c | 60 ++++++++++++++++++++++++++++++++++++++++++--- test/specificity.jl | 11 +++++++++ 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/src/subtype.c b/src/subtype.c index 3340abfc4bafc..e503b49811503 100644 --- a/src/subtype.c +++ b/src/subtype.c @@ -4730,6 +4730,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 +4802,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 +4823,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 +4888,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/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 From 9be0976f1a740dcae9f31f3405422c56baa66dd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mos=C3=A8=20Giordano?= Date: Mon, 29 Jul 2024 22:26:14 +0100 Subject: [PATCH 013/115] Add PGO/LTO/BOLT Makefiles to NEWS.md and HISTORY.md (#55282) Ref: https://github.com/JuliaLang/julia/pull/54107#issuecomment-2252826710. If accepted, I'll add the NEWS.md entry for PGO/LTO in the release-1.11 branch too. --- HISTORY.md | 3 +++ NEWS.md | 2 ++ 2 files changed, 5 insertions(+) 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/NEWS.md b/NEWS.md index c98fa6b862b67..d09581e87e4b5 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 --------------------- From 20b3af3bb06e145607e5736acdcafb6d6b14341c Mon Sep 17 00:00:00 2001 From: Zentrik Date: Mon, 29 Jul 2024 22:52:53 +0100 Subject: [PATCH 014/115] Patch curl so that it builds without BinaryBuilder (#55290) Also removes nss flag as NSS seems to have been removed from curl and I think the flag was dropped in https://github.com/curl/curl/pull/11459/files. Fixes #55286. --- deps/curl.mk | 12 ++++++++++-- deps/patches/curl-8.6.0-build.patch | 23 +++++++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 deps/patches/curl-8.6.0-build.patch 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/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" From f979ee99544f850664efc44d4b2c8c35f5a3155c Mon Sep 17 00:00:00 2001 From: N5N3 <2642243996@qq.com> Date: Tue, 30 Jul 2024 07:29:18 +0800 Subject: [PATCH 015/115] Fix `sum(bc::Broadcasted; dims = 1, init = 0)` (#43736) This PR make `has_fast_linear_indexing` rely on `IndexStyle`/`ndims` to fix `mapreduce` for `Broadcasted` with `dim > 1`. Before: ```julia julia> a = randn(100,100); julia> bc = Broadcast.instantiate(Base.broadcasted(+,a,a)); julia> sum(bc,dims = 1,init = 0.0) == sum(collect(bc), dims = 1) ERROR: MethodError: no method matching LinearIndices(::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{2}, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}, typeof(+), Tuple{Matrix{Float64}, Matrix{Float64}}}) ``` After: ```julia julia> sum(bc,dims = 1,init = 0.0) == sum(collect(bc), dims = 1) true ``` This should extend the optimized fallback to more `AbstractArray`. (e.g. `SubArray`) Test added. --- base/reducedim.jl | 7 ++----- test/broadcast.jl | 4 ++++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/base/reducedim.jl b/base/reducedim.jl index 1d74fb0d498a5..4ab786804ff4c 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 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: From fb6b7904b7bfd7b22d4b1b6779cced428e940ca0 Mon Sep 17 00:00:00 2001 From: N5N3 <2642243996@qq.com> Date: Tue, 30 Jul 2024 08:04:09 +0800 Subject: [PATCH 016/115] typeintersect: fix bounds merging during inner `intersect_all` (#55299) This PR reverts the optimization from 748149efb3b43e732eab8e9e4276e0ee2bcfa65b (part of #48167), while keeping the fix for merging occurs_inv/occurs_cov, as that optimzation makes no sense especially when typevar occurs both inside and outside the inner intersection. Close #55206 --- src/subtype.c | 190 ++++++++++++++---------------------------------- test/subtype.jl | 43 +++++++++-- 2 files changed, 92 insertions(+), 141 deletions(-) diff --git a/src/subtype.c b/src/subtype.c index e503b49811503..6f6520c5df980 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; @@ -3312,7 +3300,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 +3329,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 +4030,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 +4057,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 +4112,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 +4122,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 +4133,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 +4629,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)) diff --git a/test/subtype.jl b/test/subtype.jl index c26f4fc9d30e2..af023ef8ca72f 100644 --- a/test/subtype.jl +++ b/test/subtype.jl @@ -2380,12 +2380,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 +2583,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 From e0f2e295091dc293561a15d302d22bf96d810018 Mon Sep 17 00:00:00 2001 From: Elliot Saba Date: Mon, 29 Jul 2024 22:10:30 -0700 Subject: [PATCH 017/115] Add `lbt_forwarded_funcs()` to debug LBT forwarding issues (#55302) It can be very helpful, when struggling with LBT forwarding, to see what functions were actually forwarded to a new library. This utility function makes it easy to query which functions are forwarded to that library. --- stdlib/LinearAlgebra/src/lbt.jl | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) 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. From 58623010fdcb71b54f15c35b370f6b0c54134220 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Tue, 30 Jul 2024 11:33:35 +0200 Subject: [PATCH 018/115] inference: Allow any non-nothing source in ci_has_source for extern owner (#55294) In updating DAECompiler to the new engine API, I was running some trouble, because the source it produces is not a `CodeInfo` or a `String` (which is fine because it has a non-nothing `owner`). Adjust the test to consider any non-nothing value in .inferred valid source (at least for non-nothing CI owners). --- base/compiler/typeinfer.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/compiler/typeinfer.jl b/base/compiler/typeinfer.jl index 77547a5b30877..85bdd881042dc 100644 --- a/base/compiler/typeinfer.jl +++ b/base/compiler/typeinfer.jl @@ -1118,7 +1118,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 """ From 5d80593475da4afd5a08cce5d271484cfc567801 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Tue, 30 Jul 2024 11:34:18 +0200 Subject: [PATCH 019/115] inference: Switch to typename-based override for constprop heuristics (#55288) As mentioned in #55271, I'd like to get rid of `istopfunction` for various reasons. Rather than hardcoding constprop overrides based on binding name, this annotates the relevant TypeNames (like the existing `max_methods` override), removing the binding lookups from inference. --- base/Base.jl | 3 +++ base/abstractarray.jl | 4 ++++ base/boot.jl | 6 ++++++ base/compiler/abstractinterpretation.jl | 13 +++++-------- base/essentials.jl | 15 ++++++++++++++- src/datatype.c | 1 + src/jltypes.c | 10 ++++++---- src/julia.h | 1 + 8 files changed, 40 insertions(+), 13 deletions(-) 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..2fbae2c423196 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 diff --git a/base/boot.jl b/base/boot.jl index 1481928b319b7..3afb0e563483d 100644 --- a/base/boot.jl +++ b/base/boot.jl @@ -1012,6 +1012,12 @@ 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 + include(Core, "optimized_generics.jl") ccall(:jl_set_istopmod, Cvoid, (Any, Bool), Core, true) diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index 3b658534b5d35..98ae3486e59ee 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -1158,16 +1158,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) @@ -1180,17 +1180,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 diff --git a/base/essentials.jl b/base/essentials.jl index c4ce6dfbd4e3a..238b4a393c87c 100644 --- a/base/essentials.jl +++ b/base/essentials.jl @@ -389,7 +389,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) @@ -1245,3 +1245,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/src/datatype.c b/src/datatype.c index d5ee3eb7074c3..e7ee15a63f56e 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; } diff --git a/src/jltypes.c b/src/jltypes.c index 10b8bc937939e..fe490d2c45acb 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -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..fe511c0ced1b0 100644 --- a/src/julia.h +++ b/src/julia.h @@ -531,6 +531,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 { From 6bc2c551f825e9e98bca8db42626e8319003ecdd Mon Sep 17 00:00:00 2001 From: Neven Sajko Date: Tue, 30 Jul 2024 11:52:13 +0200 Subject: [PATCH 020/115] expand the doc string of `Union{}` (#55291) Give some characterizations/relevant terms from type theory. Clarify the, previously unexplained, usage of "bottom" in names. Cross-reference the subtyping doc string. Add an entry to the doctest, clarifying the last sentence. --- base/docs/basedocs.jl | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/base/docs/basedocs.jl b/base/docs/basedocs.jl index dd4c8d64e7d4e..2ed1bd98caa5c 100644 --- a/base/docs/basedocs.jl +++ b/base/docs/basedocs.jl @@ -3185,14 +3185,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 From 125bac4b9022ad9ff9c355e4810f94512739bac6 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Tue, 30 Jul 2024 18:58:09 +0900 Subject: [PATCH 021/115] inference: cleans up abstract interpretation code (#55308) - propagate the lattice that was not propagated - remove unused `condargs` allocation --- base/compiler/abstractinterpretation.jl | 45 ++++++++++++------------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index 98ae3486e59ee..22bc1cf046d98 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -17,7 +17,7 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f), arginfo::ArgInfo, si::StmtInfo, @nospecialize(atype), sv::AbsIntState, max_methods::Int) 𝕃ₚ, 𝕃ᵢ = ipo_lattice(interp), typeinf_lattice(interp) - ⊑ₚ = ⊑(𝕃ₚ) + ⊑ₚ, ⊔ₚ, ⊔ᵢ = partialorder(𝕃ₚ), join(𝕃ₚ), join(𝕃ᵢ) 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, @@ -37,7 +37,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 +96,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 +156,8 @@ 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) + 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 +165,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 +182,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 +240,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 +367,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 +387,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 @@ -412,6 +413,7 @@ function from_interconditional(𝕃ᵢ::AbstractLattice, @nospecialize(rt), sv:: 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 +449,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 @@ -1368,7 +1370,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 @@ -1385,10 +1386,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 From 686804d2c9f94e8b51de56320dabfaf6c630c17e Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Tue, 30 Jul 2024 13:29:24 +0000 Subject: [PATCH 022/115] LAPACK: Aggressive constprop to concretely infer syev!/syevd! (#55295) Currently, these are inferred as a 2-Tuple of possible return types depending on `jobz`, but since `jobz` is usually a constant, we may propagate it aggressively and have the return types inferred concretely. --- stdlib/LinearAlgebra/src/lapack.jl | 8 ++++---- stdlib/LinearAlgebra/test/lapack.jl | 10 ++++++++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/stdlib/LinearAlgebra/src/lapack.jl b/stdlib/LinearAlgebra/src/lapack.jl index e9cfacfcd0cfd..6d1d871ed85fd 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) 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 From c66513fd639d8b73a6a3e554a57c19e4f5f038b9 Mon Sep 17 00:00:00 2001 From: Jakob Nybo Nissen Date: Tue, 30 Jul 2024 21:21:25 +0200 Subject: [PATCH 023/115] Random: Mark unexported public symbols as public (#55148) The following symbols: `seed!, default_rng, Sampler, SamplerType, SamplerTrivial, SamplerSimple` Are documented in the Julia documentation and unexported, but not marked as public. Co-authored-by: Max Horn --- stdlib/Random/src/Random.jl | 2 ++ 1 file changed, 2 insertions(+) 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 """ From f225f8428f1a0d34cf837ee40bb2380b515eabab Mon Sep 17 00:00:00 2001 From: Matt Bauman Date: Wed, 31 Jul 2024 05:06:39 -0400 Subject: [PATCH 024/115] avoid overflowing show for OffsetArrays around typemax (#55303) --- base/show.jl | 4 ++-- test/offsetarray.jl | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) 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/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) From 8d41d25e69ff7419f7b11c8d105884fa2edea925 Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Wed, 31 Jul 2024 12:54:51 +0200 Subject: [PATCH 025/115] Revert changing `wrap` on `Memory` to `view` and make `wrap` non-public. (#54927) Fixes https://github.com/JuliaLang/julia/issues/54768 --- base/array.jl | 53 ++++++++++++++++++++++++++++++++++++++++++ base/genericmemory.jl | 25 -------------------- base/iobuffer.jl | 12 ++++++---- base/strings/string.jl | 5 +--- test/arrayops.jl | 53 ++++++++++++++---------------------------- test/core.jl | 3 --- 6 files changed, 79 insertions(+), 72 deletions(-) diff --git a/base/array.jl b/base/array.jl index 32c543ff12638..008a52abb952e 100644 --- a/base/array.jl +++ b/base/array.jl @@ -3064,3 +3064,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/genericmemory.jl b/base/genericmemory.jl index 32c15a22e0db1..6df6c880f74a8 100644 --- a/base/genericmemory.jl +++ b/base/genericmemory.jl @@ -316,31 +316,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/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/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/test/arrayops.jl b/test/arrayops.jl index f4bb2dc7372f8..e407ad7233bc2 100644 --- a/test/arrayops.jl +++ b/test/arrayops.jl @@ -3219,42 +3219,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) - - # 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) +@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) + + 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 diff --git a/test/core.jl b/test/core.jl index 3a3f6e6d1b6cd..e765d5a2ab7d7 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 From d64ebd366a830e1ff85c7520145cc66b25de5f74 Mon Sep 17 00:00:00 2001 From: igrqb <100824876+igrqb@users.noreply.github.com> Date: Wed, 31 Jul 2024 22:45:18 +1000 Subject: [PATCH 026/115] Update help info for qr.jl (#55320) 'Rather than' seems to be the correct intent of the help info. This would mean that Julia stores the result of QR in compact form instead of (=rather than) storing in dense form. 'Rather as' would mean that Julia stores Q and R in two separate dense matrices and not in compact form. --- stdlib/LinearAlgebra/src/qr.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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) From fdecc597878ddd29c16463c621adb4b6d0a25462 Mon Sep 17 00:00:00 2001 From: jariji <96840304+jariji@users.noreply.github.com> Date: Wed, 31 Jul 2024 10:59:55 -0700 Subject: [PATCH 027/115] Restrict argument to `isleapyear(::Integer)` (#55317) In 1.10 we have ```jl julia> isleapyear(Year(1992)) false ``` which is semantically incorrect because `Year(1992)` is a duration (1992 years), not an instant. This PR restricts the currently unrestricted argument to integers. --- stdlib/Dates/src/types.jl | 2 +- stdlib/Dates/test/types.jl | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) 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) From 5a904ac97a89506456f5e890b8dabea57bd7a0fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Guedes?= Date: Wed, 31 Jul 2024 15:25:34 -0300 Subject: [PATCH 028/115] Enable per thread register state cache on libunwind (#55049) Looking into a profile recently I realized that when recording backtraces the CPU utilization is mostly dominated by lookups/updates to libunwind's register state cache (`get_rs_cache`, `put_rs_cache`): ![Screenshot from 2024-07-05 19-29-45](https://github.com/JuliaLang/julia/assets/5301739/5e65f867-6dc8-4d55-8669-aaf1f756a2ac) It is also worth noting that those functions are taking a lock and using `sigprocmask` which does not scale, so by recording backtraces in parallel we get: ![Screenshot from 2024-07-05 19-30-21](https://github.com/JuliaLang/julia/assets/5301739/ed3124dd-f340-4b52-a7f9-c0a203f935b6) And this translates to these times on a recent laptop (Linux X86_64): ``` julia> @time for i in 1:1000000 Base.backtrace() end 8.286924 seconds (32.00 M allocations: 8.389 GiB, 1.46% gc time) julia> @time Threads.@sync for i in 1:16 Threads.@spawn for j in 1:1000000 Base.backtrace() end end 20.448630 seconds (160.01 M allocations: 123.740 GiB, 8.05% gc time, 0.43% compilation time: 18% of which was recompilation) ``` Good news is that libunwind already has the solution for this in the form of the `--enable-per-thread-cache` build option which uses a thread local cache for register state instead of the default global one ([1](https://libunwind-devel.nongnu.narkive.com/V3gtFUL9/question-about-performance-of-threaded-access-in-libunwind)). But this is not without some hiccups due to how we `dlopen` libunwind so we need a small patch ([2](https://libunwind-devel.nongnu.narkive.com/QG1K3Uke/tls-model-initial-exec-attribute-prevents-dynamic-loading-of-libunwind-via-dlopen)). By applying those changes we get: ``` julia> @time for i in 1:1000000 Base.backtrace() end 2.378070 seconds (32.00 M allocations: 8.389 GiB, 4.72% gc time) julia> @time Threads.@sync for i in 1:16 Threads.@spawn for j in 1:1000000 Base.backtrace() end end 3.657772 seconds (160.01 M allocations: 123.740 GiB, 52.05% gc time, 2.33% compilation time: 19% of which was recompilation) ``` Single-Threaded: ![Screenshot from 2024-07-05 20-25-49](https://github.com/JuliaLang/julia/assets/5301739/ebc87952-e51f-488c-92f4-72aed5abb93a) Multi-Threaded: ![Screenshot from 2024-07-05 20-26-32](https://github.com/JuliaLang/julia/assets/5301739/0ea2160a-60e8-49ea-af62-7d8ffc35c963) As a companion to this PR I have created another one for applying the same change to LibUnwind_jll [on Yggdrasil](https://github.com/JuliaPackaging/Yggdrasil/pull/9030). After that lands we can bump the version here. --- deps/checksums/unwind | 48 +++++++++---------- .../libunwind-disable-initial-exec-tls.patch | 44 +++++++++++++++++ deps/unwind.mk | 8 +++- src/threading.c | 6 +++ stdlib/LibUnwind_jll/Project.toml | 2 +- 5 files changed, 81 insertions(+), 27 deletions(-) create mode 100644 deps/patches/libunwind-disable-initial-exec-tls.patch 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/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/unwind.mk b/deps/unwind.mk index 501ea6b8aedcc..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 diff --git a/src/threading.c b/src/threading.c index 0c4e1ccf70eb0..2f658832f2220 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; } 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" From dcd8cad90d7986d77f1392c773a2e01be6f1c55f Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Wed, 31 Jul 2024 18:22:42 -0400 Subject: [PATCH 029/115] add `delete` for NamedTuple (#55270) from #27725 Co-authored-by: Jeffrey Sarnoff --- base/namedtuple.jl | 18 ++++++++++++++++++ test/namedtuple.jl | 7 +++++++ 2 files changed, 25 insertions(+) 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/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,) From 920c936f86ee41d3c17b403cc8d6e947c6fbc93d Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Fri, 5 Jul 2024 14:01:43 -0400 Subject: [PATCH 030/115] avoid unnecessary inexact check in `write(::IO, ::String)` --- base/strings/io.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/strings/io.jl b/base/strings/io.jl index 46353ff6f7c29..aa2bc8afa170f 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) """ From ecf08ce3fa1d540dc774601249bf8ef52bfc6d43 Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Thu, 25 Jul 2024 16:19:05 -0400 Subject: [PATCH 031/115] improve task_done_hook code for trimming --- base/task.jl | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) 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 From b0c22817ca42f28d535e3c1c957946eb2bd207e4 Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Thu, 25 Jul 2024 16:28:24 -0400 Subject: [PATCH 032/115] make `Sysinfo.__init__` easier to compile --- base/sysinfo.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From 761a8cf442e49bb76434cde15dfab7d9318e19af Mon Sep 17 00:00:00 2001 From: Diogo Netto <61364108+d-netto@users.noreply.github.com> Date: Wed, 31 Jul 2024 21:29:05 -0300 Subject: [PATCH 033/115] WIP/NFC: create GC interface for third-party GCs (#55256) Prelude to the MMTk integration. Creates an interface header specifying the functions that a third-party GC must implement to plug into Julia, and also splits the stock Julia GC implementation into a separate file `gc-stock.c`. In the future, we'll include a few pre-processor guards to ensure some of these files are not compiled if MMTk is enabled. A WIP design document describing the rationale behind the interface and the plan for MMTk integration should be in this [design document](https://docs.google.com/document/d/1v0jtSrIpdEDNOxj5S9g1jPqSpuAkNWhr_T8ToFC9RLI/edit) (feedback is welcome at this stage!). ## TODO - [x] Ensure functions in `gc-interface.h` are only declared in this header. - [x] Add allocation fast-path & codegen write-barriers into the interface. --- base/timing.jl | 4 +- doc/src/devdocs/object.md | 4 +- src/Makefile | 20 +- src/gc-alloc-profiler.cpp | 1 - src/gc-common.c | 506 ++++++++++++++++++++++++++ src/gc-common.h | 176 ++++++++++ src/gc-debug.c | 3 +- src/gc-heap-snapshot.cpp | 5 +- src/gc-heap-snapshot.h | 1 + src/gc-interface.h | 248 +++++++++++++ src/gc-page-profiler.c | 1 + src/gc-page-profiler.h | 2 +- src/gc-pages.c | 3 +- src/gc-stacks.c | 3 +- src/{gc.c => gc-stock.c} | 625 +++++---------------------------- src/{gc.h => gc-stock.h} | 72 +--- src/julia.h | 23 +- src/julia_internal.h | 29 +- src/llvm-final-gc-lowering.cpp | 62 +--- src/llvm-gc-interface-passes.h | 413 ++++++++++++++++++++++ src/llvm-late-gc-lowering.cpp | 360 +------------------ src/scheduler.c | 110 +----- src/signals-unix.c | 6 +- src/stackwalk.c | 2 +- src/threading.c | 2 - 25 files changed, 1489 insertions(+), 1192 deletions(-) create mode 100644 src/gc-common.c create mode 100644 src/gc-common.h create mode 100644 src/gc-interface.h rename src/{gc.c => gc-stock.c} (89%) rename src/{gc.h => gc-stock.h} (92%) create mode 100644 src/llvm-gc-interface-passes.h 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/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/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/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 971dbe92d7fac..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 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 3ab0aa4b1bf1b..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) { @@ -3997,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; @@ -4018,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) @@ -4035,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) @@ -4290,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 0d8421912dbc7..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); @@ -580,6 +511,7 @@ 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; diff --git a/src/julia.h b/src/julia.h index fe511c0ced1b0..29899f2985a4f 100644 --- a/src/julia.h +++ b/src/julia.h @@ -82,6 +82,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" @@ -1047,35 +1048,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 { @@ -1107,7 +1087,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 392fe8fd9a1fb..2ec4c9da7452b 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -311,7 +311,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,8 +350,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; -JL_DLLEXPORT void *jl_gc_perm_alloc(size_t sz, int zero, - unsigned align, unsigned offset) JL_NOTSAFEPOINT; void gc_sweep_sysimg(void); @@ -544,17 +542,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, ...); @@ -590,14 +577,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; @@ -945,9 +924,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); @@ -957,7 +934,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; @@ -1301,6 +1277,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 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/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-unix.c b/src/signals-unix.c index aa4d1626a4305..f01f2fcfb739a 100644 --- a/src/signals-unix.c +++ b/src/signals-unix.c @@ -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/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/threading.c b/src/threading.c index 2f658832f2220..8f37ee814056c 100644 --- a/src/threading.c +++ b/src/threading.c @@ -465,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_ From b759fe29a3e1f84b7cb928f1f87417d43f7fc72a Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Wed, 31 Jul 2024 20:48:42 -0400 Subject: [PATCH 034/115] Profile: Fix stdlib paths (#55327) --- src/signals-mach.c | 8 ++++---- src/signals-unix.c | 8 ++++---- src/signals-win.c | 8 ++++---- stdlib/Profile/src/Profile.jl | 4 ++-- 4 files changed, 14 insertions(+), 14 deletions(-) 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 f01f2fcfb739a..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 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/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) From 602b582a66ca15bbfe2328546ee04f98167e67c9 Mon Sep 17 00:00:00 2001 From: Elliot Saba Date: Wed, 31 Jul 2024 20:24:02 -0700 Subject: [PATCH 035/115] [libblastrampoline] Bump to v5.11.0 (#55330) This includes support to properly forward MKL v2024's ILP64 CBLAS symbols, which fixes this [Enzyme issue](https://github.com/EnzymeAD/Enzyme.jl/issues/1683) --- deps/blastrampoline.version | 6 +- deps/checksums/blastrampoline | 68 +++++++++++------------ stdlib/libblastrampoline_jll/Project.toml | 2 +- 3 files changed, 38 insertions(+), 38 deletions(-) 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/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/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" From 0f51a6375f2ced11a47ea8266a2bc87f94e69a25 Mon Sep 17 00:00:00 2001 From: "Steven G. Johnson" Date: Thu, 1 Aug 2024 00:13:31 -0400 Subject: [PATCH 036/115] ascii=true and fullhex=true flags for escape_string (#55099) --- NEWS.md | 3 +++ base/strings/io.jl | 30 +++++++++++++++++++++--------- test/strings/io.jl | 5 +++++ 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/NEWS.md b/NEWS.md index d09581e87e4b5..2eb8096bcd0d2 100644 --- a/NEWS.md +++ b/NEWS.md @@ -92,6 +92,9 @@ 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]) diff --git a/base/strings/io.jl b/base/strings/io.jl index 46353ff6f7c29..6de72e07cd172 100644 --- a/base/strings/io.jl +++ b/base/strings/io.jl @@ -382,8 +382,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 +398,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 +433,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 +448,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 +462,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/test/strings/io.jl b/test/strings/io.jl index f1fe0c24e8aea..79e11d8cf5184 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([],",") == "" From 5092379cf4b586cc15e16c14f27eebc4fb5ab11c Mon Sep 17 00:00:00 2001 From: Neven Sajko Date: Thu, 1 Aug 2024 08:46:23 +0200 Subject: [PATCH 037/115] document the return types of `fieldname` and `fieldnames` (#55259) --- base/reflection.jl | 11 +++++++++++ 1 file changed, 11 insertions(+) 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 From 2179f146945039dca4093ea511c8fe6ea51276c9 Mon Sep 17 00:00:00 2001 From: Neven Sajko Date: Thu, 1 Aug 2024 10:16:43 +0200 Subject: [PATCH 038/115] better type inference for several functions taking `NTuple` args (#55124) Improves the abstract return type inference for these functions, for homogeneous tuple arguments: * `tail` * `front` * `reverse` * `circshift` Example: ```julia f(g, t::Type{<:Tuple}) = println(Core.Compiler.return_type(g, t)) f(Base.tail, Tuple{NTuple}) f(Base.front, Tuple{NTuple}) f(reverse, Tuple{NTuple}) f(circshift, Tuple{NTuple,Int}) ``` Results before: ```julia Tuple Tuple Tuple Tuple ``` Results after: ```julia NTuple{N, T} where {N, T} NTuple{N, T} where {N, T} NTuple{N, T} where {N, T} NTuple{N, T} where {N, T} ``` Updates #54495 --- base/essentials.jl | 8 +++++++- base/ntuple.jl | 2 +- base/tuple.jl | 16 +++++++++++++--- test/tuple.jl | 7 +++++++ 4 files changed, 28 insertions(+), 5 deletions(-) diff --git a/base/essentials.jl b/base/essentials.jl index 238b4a393c87c..c6a6d43ce17e1 100644 --- a/base/essentials.jl +++ b/base/essentials.jl @@ -501,7 +501,13 @@ julia> Base.tail(()) ERROR: ArgumentError: Cannot call tail on an empty tuple. ``` """ -tail(x::Tuple) = argtail(x...) +function tail(x::Tuple{Any,Vararg}) + y = argtail(x...)::Tuple + if x isa NTuple # help the type inference + y = y::NTuple + end + y +end tail(::Tuple{}) = throw(ArgumentError("Cannot call tail on an empty tuple.")) function unwrap_unionall(@nospecialize(a)) diff --git a/base/ntuple.jl b/base/ntuple.jl index f81d2686b9764..4adab38a8ee82 100644 --- a/base/ntuple.jl +++ b/base/ntuple.jl @@ -95,5 +95,5 @@ end function reverse(t::NTuple{N}) where N ntuple(Val{N}()) do i t[end+1-i] - end + end::NTuple end diff --git a/base/tuple.jl b/base/tuple.jl index fc213410cfd7c..5f74d486e1e69 100644 --- a/base/tuple.jl +++ b/base/tuple.jl @@ -340,9 +340,15 @@ ERROR: ArgumentError: Cannot call front on an empty tuple. """ function front(t::Tuple) @inline - _front(t...) + if t === () + throw(ArgumentError("Cannot call front on an empty tuple.")) + end + r = _front(t...)::Tuple + if t isa NTuple # help the type inference + r = r::NTuple + end + r end -_front() = throw(ArgumentError("Cannot call front on an empty tuple.")) _front(v) = () function _front(v, t...) @inline @@ -699,5 +705,9 @@ function circshift(x::Tuple{Any,Any,Any,Vararg{Any,N}}, shift::Integer) where {N @inline len = N + 3 j = mod1(shift, len) - ntuple(k -> getindex(x, k-j+ifelse(k>j,0,len)), Val(len))::Tuple + y = ntuple(k -> getindex(x, k-j+ifelse(k>j,0,len)), Val(len))::Tuple + if x isa NTuple # help the type inference + y = y::NTuple + end + y end diff --git a/test/tuple.jl b/test/tuple.jl index b1894bd2bb6ce..59897c8adfdb2 100644 --- a/test/tuple.jl +++ b/test/tuple.jl @@ -845,3 +845,10 @@ end end end end + +@testset "abstract return type inference for homogeneous tuples" begin + @test NTuple == Core.Compiler.return_type(Base.tail, Tuple{NTuple}) + @test NTuple == Core.Compiler.return_type(Base.front, Tuple{NTuple}) + @test NTuple == Core.Compiler.return_type(reverse, Tuple{NTuple}) + @test NTuple == Core.Compiler.return_type(circshift, Tuple{NTuple,Int}) +end From df1976d500914bebd5651bf56c13153f49e153f9 Mon Sep 17 00:00:00 2001 From: Jakob Nybo Nissen Date: Thu, 1 Aug 2024 11:28:30 +0200 Subject: [PATCH 039/115] Define parent(::GenericMemoryRef) (#55325) It would be nice to have function to extract the `GenericMemory` underlying the `GenericMemoryRef`, without accessing its undocumented field `.mem`. I'm not sure `parent` is the right function for this, but it's the best I could think of. --- base/genericmemory.jl | 2 ++ test/arrayops.jl | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/base/genericmemory.jl b/base/genericmemory.jl index 6df6c880f74a8..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) diff --git a/test/arrayops.jl b/test/arrayops.jl index e407ad7233bc2..c904a52e8cad9 100644 --- a/test/arrayops.jl +++ b/test/arrayops.jl @@ -3246,3 +3246,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 From 7c6a1a217efa25f9f700b1c30301ab596f391615 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Thu, 1 Aug 2024 09:47:19 -0400 Subject: [PATCH 040/115] inference: Remove special casing for `!` (#55271) We have a handful of cases in inference where we look up functions by name (using `istopfunction`) and give them special behavior. I'd like to remove these. They're not only aesthetically ugly, but because they depend on binding lookups, rather than values, they have unclear semantics as those bindings change. They are also unsound should a user use the same name for something differnt in their own top modules (of course, it's unlikely that a user would do such a thing, but it's bad that they can't). This particular PR removes the special case for `!`, which was there to strengthen the inference result for `!` on Conditional. However, with a little bit of strengthening of the rest of the system, this can be equally well evaluated through the existing InterConditional mechanism. --- base/compiler/abstractinterpretation.jl | 46 ++++++++++++++++++++----- base/compiler/inferencestate.jl | 3 ++ base/compiler/tfuncs.jl | 11 +++++- test/compiler/inference.jl | 5 +++ 4 files changed, 56 insertions(+), 9 deletions(-) diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index 22bc1cf046d98..a7602f8cd4134 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -13,6 +13,31 @@ 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) @@ -156,6 +181,15 @@ 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 + + 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 @@ -409,6 +443,9 @@ 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 @@ -2217,13 +2254,6 @@ 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, :!==) # 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) @@ -3194,7 +3224,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/inferencestate.jl b/base/compiler/inferencestate.jl index c358b1177251f..38011656e41ea 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 diff --git a/base/compiler/tfuncs.jl b/base/compiler/tfuncs.jl index 28e883d83312c..b40f65ab3ca1d 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) diff --git a/test/compiler/inference.jl b/test/compiler/inference.jl index 8b6da828af54d..9ae98b884bef4 100644 --- a/test/compiler/inference.jl +++ b/test/compiler/inference.jl @@ -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 From 0ef8a91e490dfaa90cb6e4781ca0445c7f991933 Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Thu, 1 Aug 2024 14:46:19 +0000 Subject: [PATCH 041/115] Preserve structure in scaling triangular matrices by NaN (#55310) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses the `Matrix` cases from https://github.com/JuliaLang/julia/issues/55296. This restores the behavior to match that on v1.10, and preserves the structure of the matrix on scaling by `NaN`. This behavior is consistent with the strong-zero behavior for other structured matrix types, and the scaling may be seen to be occurring in the vector space corresponding to the filled elements. After this, ```julia julia> UpperTriangular(rand(2,2)) * NaN 2×2 UpperTriangular{Float64, Matrix{Float64}}: NaN NaN ⋅ NaN ``` cc. @mikmoore --- stdlib/LinearAlgebra/src/triangular.jl | 61 +++++++++++++++++++++++-- stdlib/LinearAlgebra/test/triangular.jl | 14 ++++++ 2 files changed, 71 insertions(+), 4 deletions(-) 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/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 From c6732a79494f604e0f320ea451856a1c10511659 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Fri, 2 Aug 2024 04:51:21 -0400 Subject: [PATCH 042/115] Avoid duplicate stat calls during startup/loading (#55331) Avoids immediately successive stat calls for the same path during startup & loading. According to MacOS Instruments this reduces `stat64` calls during `--start=no -e "using Pkg"` from 844 to 672. On MacOS I don't see a speed improvement, but on WSL2 @timholy reported the test from https://github.com/JuliaLang/julia/issues/55171 sees a modest improvement. This PR (10 iterations) ``` tim@diva:~/.julia/bin$ time for i in {1..10}; do ./cli --help &> /dev/null; done real 0m2.999s user 0m3.547s sys 0m6.552s ``` master ``` real 0m3.217s user 0m3.794s sys 0m6.700s ``` 1.11-rc2: ``` real 0m3.746s user 0m4.169s sys 0m6.755s ``` I left the `@debug`s in as they might be useful for similar investigations. --- base/client.jl | 2 ++ base/loading.jl | 12 +++++++----- base/stat.jl | 10 ++++++++-- 3 files changed, 17 insertions(+), 7 deletions(-) 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/loading.jl b/base/loading.jl index fa46819c5731c..c273e4505701f 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 @@ -3809,7 +3810,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 +3832,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/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 From 2635dea5981e71fb672bcb72a17d9fb99195ec54 Mon Sep 17 00:00:00 2001 From: Felix Wechsler Date: Fri, 2 Aug 2024 14:35:04 +0200 Subject: [PATCH 043/115] Add insertdims method which is inverse to dropdims (#45793) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Example: ```julia julia> a = [1 2; 3 4] 2×2 Matrix{Int64}: 1 2 3 4 julia> b = insertdims(a, dims=(1,4)) 1×2×2×1 Array{Int64, 4}: [:, :, 1, 1] = 1 3 [:, :, 2, 1] = 2 4 julia> b[1,1,1,1] = 5; a 2×2 Matrix{Int64}: 5 2 3 4 julia> b = insertdims(a, dims=(1,2)) 1×1×2×2 Array{Int64, 4}: [:, :, 1, 1] = 5 [:, :, 2, 1] = 3 [:, :, 1, 2] = 2 [:, :, 2, 2] = 4 julia> b = insertdims(a, dims=(1,3)) 1×2×1×2 Array{Int64, 4}: [:, :, 1, 1] = 5 3 [:, :, 1, 2] = 2 4 ``` --------- Co-authored-by: Neven Sajko Co-authored-by: Lilith Orion Hafner Co-authored-by: Mark Kittisopikul --- NEWS.md | 1 + base/abstractarraymath.jl | 64 +++++++++++++++++++++++++++++++++++++++ base/exports.jl | 1 + doc/src/base/arrays.md | 1 + test/arrayops.jl | 29 ++++++++++++++++++ 5 files changed, 96 insertions(+) diff --git a/NEWS.md b/NEWS.md index 2eb8096bcd0d2..6f12b8ff389cd 100644 --- a/NEWS.md +++ b/NEWS.md @@ -72,6 +72,7 @@ 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` New library features -------------------- 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/exports.jl b/base/exports.jl index 1f0ccdf6b8c36..dbe12f933e597 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -407,6 +407,7 @@ export indexin, argmax, argmin, + insertdims, invperm, invpermute!, isassigned, 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/test/arrayops.jl b/test/arrayops.jl index c904a52e8cad9..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;] From 2ec9143d2e5982bb4a6bc31367aa8fca446ec007 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Fri, 2 Aug 2024 11:25:34 -0400 Subject: [PATCH 044/115] Move `typename` and `<:` to Core and have inference check by value (#55289) As mentioned in #55271, the `istopfunction` binding-based comparisons are problematic. In #55272 and #55273, I attempted to remove the inference special cases for `>:` and `typename` (respectively) entirely, but for differing reasons (`>:` gets too many extra specializations, `typename` loses precision), those PRs are suboptimal. As discussed in #55273, this PR instead moves these functions to Core, so that both `Core.Compiler` and `Base` share the function object, allowing inference to detect them and apply the special handling by simple value-comparison. --- - closes #55273 --- base/boot.jl | 23 +++++++++++++++++++++++ base/compiler/abstractinterpretation.jl | 6 +++--- base/compiler/ssair/inlining.jl | 4 ++-- base/compiler/utilities.jl | 9 --------- base/errorshow.jl | 9 +++++++++ base/essentials.jl | 10 +--------- base/operators.jl | 8 ++++++-- test/reflection.jl | 2 +- 8 files changed, 45 insertions(+), 26 deletions(-) diff --git a/base/boot.jl b/base/boot.jl index 3afb0e563483d..f7aee9677e2f2 100644 --- a/base/boot.jl +++ b/base/boot.jl @@ -1018,6 +1018,29 @@ 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/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index a7602f8cd4134..6a7d90a7bcb21 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -2254,7 +2254,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 == 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 @@ -2264,7 +2264,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 @@ -2274,7 +2274,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) 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/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/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 c6a6d43ce17e1..2e76235cba9a6 100644 --- a/base/essentials.jl +++ b/base/essentials.jl @@ -581,15 +581,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)))) diff --git a/base/operators.jl b/base/operators.jl index dc3c01e5645cc..b7605ba004b7a 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}) @@ -346,6 +348,7 @@ true === const ≡ = === +import Core: !== """ !==(x, y) ≢(x,y) @@ -363,7 +366,8 @@ julia> a ≢ a false ``` """ -!==(@nospecialize(x), @nospecialize(y)) = !(x === y) +!== + const ≢ = !== """ 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 From b967cf0c20e09c21c5dc28eedca124d34750ea47 Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Fri, 2 Aug 2024 16:09:54 +0000 Subject: [PATCH 045/115] LinearAlgebra: remove internal function _makevector (#55345) It seems a bit unnecessary to have a function to carry out a `convert`, instead of calling `convert` directly. --- stdlib/LinearAlgebra/src/LinearAlgebra.jl | 4 ---- stdlib/LinearAlgebra/src/bidiag.jl | 4 ++-- stdlib/LinearAlgebra/src/diagonal.jl | 6 +++--- 3 files changed, 5 insertions(+), 9 deletions(-) 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/bidiag.jl b/stdlib/LinearAlgebra/src/bidiag.jl index ddfc6af60ef75..34ec92062ae01 100644 --- a/stdlib/LinearAlgebra/src/bidiag.jl +++ b/stdlib/LinearAlgebra/src/bidiag.jl @@ -252,8 +252,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 diff --git a/stdlib/LinearAlgebra/src/diagonal.jl b/stdlib/LinearAlgebra/src/diagonal.jl index ff8350d8ddeb1..8f643a0054719 100644 --- a/stdlib/LinearAlgebra/src/diagonal.jl +++ b/stdlib/LinearAlgebra/src/diagonal.jl @@ -684,9 +684,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 From 1dffd7752de2409b5f6c81fdcc1f33118127725e Mon Sep 17 00:00:00 2001 From: Matt Bauman Date: Fri, 2 Aug 2024 13:44:56 -0400 Subject: [PATCH 046/115] mapreduce: don't inbounds unknown functions (#55329) More finely scope the `@inbounds` annotations to ensure neither `f` nor `op` are erroneously `@inbounds`ed. --- base/reduce.jl | 10 +++++----- base/reducedim.jl | 37 +++++++++++++++++++------------------ test/reducedim.jl | 24 ++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 23 deletions(-) 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 4ab786804ff4c..e74fe2b765277 100644 --- a/base/reducedim.jl +++ b/base/reducedim.jl @@ -269,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 @@ -1025,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/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)) From 05d0564769dfe506389ca811075b617c9df61701 Mon Sep 17 00:00:00 2001 From: Cody Tapscott <84105208+topolarity@users.noreply.github.com> Date: Fri, 2 Aug 2024 22:29:39 -0400 Subject: [PATCH 047/115] Profile: close files when assembling heap snapshot (#55356) --- stdlib/Profile/src/heapsnapshot_reassemble.jl | 64 ++++++++++--------- 1 file changed, 33 insertions(+), 31 deletions(-) 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 From 124e0a73043aef35d073a0da83be2d5a107a12ed Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Sat, 3 Aug 2024 12:01:14 +0000 Subject: [PATCH 048/115] Condense branches in Bidiagonal indexing (#55343) --- stdlib/LinearAlgebra/src/bidiag.jl | 40 +++++++++++------------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/stdlib/LinearAlgebra/src/bidiag.jl b/stdlib/LinearAlgebra/src/bidiag.jl index 34ec92062ae01..55d3c2d5a889a 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,10 +180,8 @@ 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))) @@ -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 @@ -558,7 +546,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) From a1714caa896066081de939b900e3571429d815e6 Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Sat, 3 Aug 2024 12:01:29 +0000 Subject: [PATCH 049/115] Check only for Hermitian and not Symmetric in matrix exponentiation (#55349) For real matrices, a `Hermitian` eigenvalue problem would be equivalent to a `Symmetric` one, and for complex matrices, there is no special complex symmetric eigensolver (it errors at present, and complex symmetric matrices might not be diagonalizable). I think the `ishermitian` branch should suffice here. Removing the symmetric branch makes the return type simpler to infer. --- stdlib/LinearAlgebra/src/dense.jl | 3 --- 1 file changed, 3 deletions(-) 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 From 3d99c24461d0cf9aac575bd6e6e90ddd32d8099b Mon Sep 17 00:00:00 2001 From: Miles Cranmer Date: Sat, 3 Aug 2024 13:29:51 +0100 Subject: [PATCH 050/115] Create `Base.Fix` as general `Fix1`/`Fix2` for partially-applied functions (#54653) This PR generalises `Base.Fix1` and `Base.Fix2` to `Base.Fix{N}`, to allow fixing a single positional argument of a function. With this change, the implementation of these is simply ```julia const Fix1{F,T} = Fix{1,F,T} const Fix2{F,T} = Fix{2,F,T} ``` Along with the PR I also add a larger suite of unittests for all three of these functions to complement the existing tests for `Fix1`/`Fix2`. ### Context There are multiple motivations for this generalization. **By creating a more general `Fix{N}` type, there is no preferential treatment of certain types of functions:** - (i) No limitation that you can only fix positions 1-2. You can now fix any position `n`. - (ii) No asymmetry between 2-argument and n-argument functions. You can now fix an argument for functions with any number of arguments. Think of this like if `Base` only had `Vector{T}` and `Matrix{T}`, and you wished to generalise it to `Array{T,N}`. It is an analogous situation here: `Fix1` and `Fix2` are now *aliases* of `Fix{N}`. - **Convenience**: - `Base.Fix1` and `Base.Fix2` are useful shorthands for creating simple anonymous functions without compiling new functions. - They are common throughout the Julia ecosystem as a shorthand for filling arguments: - `Fix1` https://github.com/search?q=Base.Fix1+language%3Ajulia&type=code - `Fix2` https://github.com/search?q=Base.Fix2+language%3Ajulia&type=code - **Less Compilation**: - Using `Fix*` reduces the need for compilation of repeatedly-used anonymous functions (which can often trigger compilation of new functions). - **Type Stability**: - `Fix`, like `Fix1` and `Fix2`, captures variables in a struct, encouraging users to use a functional paradigm for closures, preventing any potential type instabilities from boxed variables within an anonymous function. - **Easier Functional Programming**: - Allows for a stronger functional programming paradigm by supporting partial functions with _any number of arguments_. Note that this refactors `Fix1` and `Fix2` to be equal to `Fix{1}` and `Fix{2}` respectively, rather than separate structs. This is backwards compatible. Also note that this does not constrain future generalisations of `Fix{n}` for multiple arguments. `Fix{1,F,T}` is the clear generalisation of `Fix1{F,T}`, so this isn't major new syntax choices. But in a future PR you could have, e.g., `Fix{(n1,n2)}` for multiple arguments, and it would still be backwards-compatible with this. --------- Co-authored-by: Dilum Aluthge Co-authored-by: Lilith Orion Hafner Co-authored-by: Alexander Plavin Co-authored-by: Neven Sajko --- NEWS.md | 1 + base/operators.jl | 57 +++++++++++------- base/public.jl | 1 + doc/src/base/base.md | 1 + stdlib/REPL/test/repl.jl | 4 +- test/functional.jl | 126 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 167 insertions(+), 23 deletions(-) diff --git a/NEWS.md b/NEWS.md index 6f12b8ff389cd..2e9b32befe342 100644 --- a/NEWS.md +++ b/NEWS.md @@ -73,6 +73,7 @@ New library functions * `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 -------------------- diff --git a/base/operators.jl b/base/operators.jl index b7605ba004b7a..2c8070b44d704 100644 --- a/base/operators.jl +++ b/base/operators.jl @@ -1154,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 -(f::Fix1)(y) = f.f(f.x, y) +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 -""" - Fix2(f, x) +# 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...) -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)`. """ -struct Fix2{F,T} <: Function - f::F - x::T +Alias for `Fix{1}`. See [`Fix`](@ref Base.Fix). +""" +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/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/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/stdlib/REPL/test/repl.jl b/stdlib/REPL/test/repl.jl index 05db88fa0d8ac..6f0c4a5c3d6ba 100644 --- a/stdlib/REPL/test/repl.jl +++ b/stdlib/REPL/test/repl.jl @@ -1216,9 +1216,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))) 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 From f2f188d57346a0163b82740ac0a758311c41004f Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Sat, 3 Aug 2024 14:27:59 +0000 Subject: [PATCH 051/115] Ensure bidiagonal setindex! does not read indices in error message (#55342) This fixes the error message if the matrix is uninitialized. This is because a `Bidiagonal` with `uplo == 'L'` may still be `istriu` if the subdiaognal is zero. We only care about the band index in the error message, and not the values. --- stdlib/LinearAlgebra/src/bidiag.jl | 2 +- stdlib/LinearAlgebra/test/bidiag.jl | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/stdlib/LinearAlgebra/src/bidiag.jl b/stdlib/LinearAlgebra/src/bidiag.jl index 55d3c2d5a889a..5f9a64904bd38 100644 --- a/stdlib/LinearAlgebra/src/bidiag.jl +++ b/stdlib/LinearAlgebra/src/bidiag.jl @@ -184,7 +184,7 @@ end @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 diff --git a/stdlib/LinearAlgebra/test/bidiag.jl b/stdlib/LinearAlgebra/test/bidiag.jl index 2ff3e9b423702..37503efe42518 100644 --- a/stdlib/LinearAlgebra/test/bidiag.jl +++ b/stdlib/LinearAlgebra/test/bidiag.jl @@ -984,4 +984,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 From f38015f470a5fe323cfc71f711f11677dcc80599 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Sat, 3 Aug 2024 11:39:59 -0400 Subject: [PATCH 052/115] codegen: NFC refactoring to use Align type --- src/ccall.cpp | 10 +++++----- src/cgutils.cpp | 41 ++++++++++++++++++++--------------------- src/codegen.cpp | 17 ++++++++++------- src/intrinsics.cpp | 12 ++++++------ 4 files changed, 41 insertions(+), 39 deletions(-) diff --git a/src/ccall.cpp b/src/ccall.cpp index 3c2857608c163..d913ed4e27e7d 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); @@ -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..297fcb164b112 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)) { @@ -2176,7 +2175,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) { @@ -2329,7 +2328,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; @@ -2668,7 +2667,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 +3103,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 +3115,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 +3581,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 +3591,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 +3626,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 +3652,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) @@ -4046,7 +4045,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) { diff --git a/src/codegen.cpp b/src/codegen.cpp index 875beb7c287dc..d8d7a1fd23814 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -5652,7 +5652,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 +5756,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 +6869,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 +8731,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( @@ -9272,8 +9274,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 +9514,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 +9541,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); } } diff --git a/src/intrinsics.cpp b/src/intrinsics.cpp index ad89abf6ca1a2..23d272ea75e7f 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 { @@ -847,7 +847,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; From e1e5a46b002a3979f6b217f1ecd7cede83bf45fd Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Sat, 3 Aug 2024 11:43:12 -0400 Subject: [PATCH 053/115] codegen: update type of x after type-assert Later code likes to see that the type is consistent with the cgval and the unbox. --- src/intrinsics.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/intrinsics.cpp b/src/intrinsics.cpp index 23d272ea75e7f..4bfe3f184d24b 100644 --- a/src/intrinsics.cpp +++ b/src/intrinsics.cpp @@ -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)); @@ -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) { From 8bfef8f1b60155020abc9bdab8aef9788eb458ba Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Thu, 1 Aug 2024 17:11:07 +0000 Subject: [PATCH 054/115] codegen: take gc roots (and alloca alignment) more seriously Due to limitations in the LLVM implementation, we are forced to emit fairly bad code here. But we need to make sure it is still correct with respect to GC rooting. The PR 50833c84d454ef989797e035294ba27b3cca79b7 also changed the meaning of haspadding without changing all of the existing users to use the new equivalent flag (haspadding || !isbitsegal), incurring additional breakage here as well and needing more tests for that. Fixes #54720 --- src/abi_aarch64.cpp | 8 ++-- src/abi_arm.cpp | 2 +- src/abi_ppc64le.cpp | 2 +- src/cgutils.cpp | 97 ++++++++++++++++++++++++++++----------------- src/codegen.cpp | 3 ++ src/datatype.c | 14 +++---- test/atomics.jl | 6 +++ 7 files changed, 83 insertions(+), 49 deletions(-) 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/cgutils.cpp b/src/cgutils.cpp index 297fcb164b112..08d51f52b613b 100644 --- a/src/cgutils.cpp +++ b/src/cgutils.cpp @@ -2119,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)) { @@ -2133,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*); @@ -2222,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); } @@ -2269,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); @@ -2286,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; @@ -2356,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); @@ -2398,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); @@ -2430,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)}; diff --git a/src/codegen.cpp b/src/codegen.cpp index d8d7a1fd23814..ef18d9bd1b673 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -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; diff --git a/src/datatype.c b/src/datatype.c index e7ee15a63f56e..e88977dd67400 100644 --- a/src/datatype.c +++ b/src/datatype.c @@ -1250,7 +1250,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; @@ -1263,7 +1263,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; @@ -1281,7 +1281,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; } } @@ -1298,7 +1298,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; } } @@ -1316,7 +1316,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; } } @@ -2010,7 +2010,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) { @@ -2125,7 +2125,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/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) From 2a56b7876be5d9364f2b187828e82f0cef0609d0 Mon Sep 17 00:00:00 2001 From: Zentrik Date: Sun, 4 Aug 2024 10:05:44 +0100 Subject: [PATCH 055/115] Bump LLVM to v18 (#54848) Co-authored-by: Gabriel Baraldi --- deps/checksums/clang | 216 +++++++------- deps/checksums/lld | 216 +++++++------- deps/checksums/llvm | 436 ++++++++++++++--------------- deps/clang.version | 2 +- deps/lld.version | 2 +- deps/llvm-tools.version | 4 +- deps/llvm.version | 12 +- src/aotcompile.cpp | 70 ++--- src/ccall.cpp | 2 +- src/clangsa/GCChecker.cpp | 12 +- src/codegen.cpp | 6 +- src/coverage.cpp | 2 +- src/datatype.c | 4 + src/disasm.cpp | 4 + src/jitlayers.cpp | 45 ++- src/jitlayers.h | 5 + src/julia.h | 18 +- src/julia_internal.h | 22 ++ src/llvm-cpufeatures.cpp | 2 +- src/llvm-multiversioning.cpp | 6 +- src/llvm-simdloop.cpp | 2 +- src/llvm_api.cpp | 12 +- src/pipeline.cpp | 15 +- src/processor_arm.cpp | 2 +- stdlib/LLD_jll/Project.toml | 4 +- stdlib/libLLVM_jll/Project.toml | 2 +- test/llvmcall.jl | 6 +- test/llvmpasses/pipeline-prints.ll | 6 +- 28 files changed, 594 insertions(+), 541 deletions(-) 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/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/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.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/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/ccall.cpp b/src/ccall.cpp index 3c2857608c163..db7bcb3a408d0 100644 --- a/src/ccall.cpp +++ b/src/ccall.cpp @@ -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) { 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.cpp b/src/codegen.cpp index 875beb7c287dc..3a363dd3fd0c1 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; } @@ -8846,7 +8846,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); @@ -9638,7 +9638,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 e7ee15a63f56e..8a7b256db4bef 100644 --- a/src/datatype.c +++ b/src/datatype.c @@ -936,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 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/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/julia.h b/src/julia.h index 29899f2985a4f..cbe60e78c2d24 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 diff --git a/src/julia_internal.h b/src/julia_internal.h index 2ec4c9da7452b..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__ 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-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/pipeline.cpp b/src/pipeline.cpp index f0dde6aa59a40..e01645cc1f154 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 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/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/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/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/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 From 22e53624407bc443b9cb12a2380b119e3baf54e3 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Sun, 4 Aug 2024 06:21:32 -0400 Subject: [PATCH 056/115] REPL: enable import completion when in a macro (#55366) Fixes https://github.com/JuliaLang/julia/issues/55361 I think this regressed in https://github.com/JuliaLang/julia/pull/54719 given tests didn't include leading spaces/macros --- stdlib/REPL/src/REPLCompletions.jl | 9 ++++++--- stdlib/REPL/test/replcompletions.jl | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/stdlib/REPL/src/REPLCompletions.jl b/stdlib/REPL/src/REPLCompletions.jl index bc8006ec2ed5d..609a7b4d81bc0 100644 --- a/stdlib/REPL/src/REPLCompletions.jl +++ b/stdlib/REPL/src/REPLCompletions.jl @@ -900,8 +900,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 +913,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 +922,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/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 From 065d4567e771af1a642f14c482dd85b3240ec0f3 Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Sun, 4 Aug 2024 12:30:41 +0000 Subject: [PATCH 057/115] Materialize complex Symmetric matrices in eigen (#55348) Currently, `eigen` for a complex Symmetric matrix fails, as there's no specialized LAPACK function to handle such matrices. We may instead materialize the matrix and use a generic solver. While a user may do it by themselves, I think returning an answer is better than throwing an error. --- stdlib/LinearAlgebra/src/bunchkaufman.jl | 15 +++++++++------ stdlib/LinearAlgebra/src/symmetriceigen.jl | 1 + stdlib/LinearAlgebra/test/hessenberg.jl | 7 +++++++ stdlib/LinearAlgebra/test/symmetriceigen.jl | 6 ++++++ 4 files changed, 23 insertions(+), 6 deletions(-) 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/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/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/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 From f4d1381b7c1242a17815bba6febeeb9a3a40c093 Mon Sep 17 00:00:00 2001 From: James Wrigley Date: Sun, 4 Aug 2024 23:14:40 +0200 Subject: [PATCH 058/115] Document `Threads.threadid(::Task)` (#55369) This is quite handy to figure out which thread a task is running on, and I couldn't find another way to do it from outside the task. --- base/threadingconstructs.jl | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) 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) From a163483e6714631e9f6fecf141bd2dca999fbd6a Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Mon, 5 Aug 2024 06:06:39 +0000 Subject: [PATCH 059/115] Fix tr for block SymTridiagonal (#55371) This ensures that `tr` for a block `SymTridiagonal` symmetrizes the diagonal elements. --- stdlib/LinearAlgebra/src/tridiag.jl | 2 +- stdlib/LinearAlgebra/test/tridiag.jl | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/stdlib/LinearAlgebra/src/tridiag.jl b/stdlib/LinearAlgebra/src/tridiag.jl index 3198e45ad3eb8..2ff688f4b4ed1 100644 --- a/stdlib/LinearAlgebra/src/tridiag.jl +++ b/stdlib/LinearAlgebra/src/tridiag.jl @@ -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 diff --git a/stdlib/LinearAlgebra/test/tridiag.jl b/stdlib/LinearAlgebra/test/tridiag.jl index fae708c4c8db4..5dc1d01e850d8 100644 --- a/stdlib/LinearAlgebra/test/tridiag.jl +++ b/stdlib/LinearAlgebra/test/tridiag.jl @@ -471,7 +471,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 +485,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 From 996351f5f6651d1508aef3c35c7d37eb22a0fb1e Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Mon, 5 Aug 2024 06:07:12 +0000 Subject: [PATCH 060/115] Round-trippable show for `Bidiagonal` (#55347) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This changes how a `Bidiagonal` is displayed using the 2-arg `show` to a form that may be parsed. After this, ```julia julia> B = Bidiagonal([1,2,3], [1,2], :U) 3×3 Bidiagonal{Int64, Vector{Int64}}: 1 1 ⋅ ⋅ 2 2 ⋅ ⋅ 3 julia> show(B) Bidiagonal([1, 2, 3], [1, 2], :U) ``` The displayed form is a valid constructor now. --- stdlib/LinearAlgebra/src/bidiag.jl | 13 +++++++------ stdlib/LinearAlgebra/test/bidiag.jl | 6 ++---- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/stdlib/LinearAlgebra/src/bidiag.jl b/stdlib/LinearAlgebra/src/bidiag.jl index 5f9a64904bd38..e2572c0f67af9 100644 --- a/stdlib/LinearAlgebra/src/bidiag.jl +++ b/stdlib/LinearAlgebra/src/bidiag.jl @@ -264,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)) diff --git a/stdlib/LinearAlgebra/test/bidiag.jl b/stdlib/LinearAlgebra/test/bidiag.jl index 37503efe42518..3c99d0d3b6f5e 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) From 40ecf690197a7a6221cfcffd9c74799258fb4495 Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Mon, 5 Aug 2024 12:54:45 +0000 Subject: [PATCH 061/115] LinearAlgbera: pass sizes to muldiag_size_check (#55378) This will avoid having to specialize `_muldiag_size_check` on the matrix types, as we only need the sizes (and potentially `ndims`) for the error checks. --- stdlib/LinearAlgebra/src/bidiag.jl | 8 ++--- stdlib/LinearAlgebra/src/diagonal.jl | 53 +++++++++++++--------------- 2 files changed, 29 insertions(+), 32 deletions(-) diff --git a/stdlib/LinearAlgebra/src/bidiag.jl b/stdlib/LinearAlgebra/src/bidiag.jl index e2572c0f67af9..0caaec02b5056 100644 --- a/stdlib/LinearAlgebra/src/bidiag.jl +++ b/stdlib/LinearAlgebra/src/bidiag.jl @@ -461,7 +461,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) @@ -482,7 +482,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] @@ -494,7 +494,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]) @@ -519,7 +519,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] diff --git a/stdlib/LinearAlgebra/src/diagonal.jl b/stdlib/LinearAlgebra/src/diagonal.jl index 8f643a0054719..9cd13b4d26f00 100644 --- a/stdlib/LinearAlgebra/src/diagonal.jl +++ b/stdlib/LinearAlgebra/src/diagonal.jl @@ -293,42 +293,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 +334,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 +346,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 +357,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 +449,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 +466,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 From 4200203453c9c47c2df88f0c3b90dec46aeb2620 Mon Sep 17 00:00:00 2001 From: Satvik Date: Mon, 5 Aug 2024 12:44:48 -0700 Subject: [PATCH 062/115] Replace `@async` mentions in manual with `Threads.@spawn` (#55315) --- doc/src/base/parallel.md | 2 +- doc/src/devdocs/probes.md | 6 +++--- doc/src/manual/asynchronous-programming.md | 10 +++++----- doc/src/manual/distributed-computing.md | 8 ++++---- doc/src/manual/faq.md | 6 +++--- doc/src/manual/methods.md | 4 ++-- doc/src/manual/networking-and-streams.md | 14 +++++++------- doc/src/manual/performance-tips.md | 2 +- doc/src/manual/running-external-programs.md | 4 ++-- 9 files changed, 28 insertions(+), 28 deletions(-) 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/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) ``` From e38e4db8f80f91ba0968736936ce4fcb1c835240 Mon Sep 17 00:00:00 2001 From: GHTaarn <62629455+GHTaarn@users.noreply.github.com> Date: Mon, 5 Aug 2024 21:52:35 +0200 Subject: [PATCH 063/115] Make REPL.TerminalMenus and some if its symbols public (#55307) --- stdlib/REPL/src/REPL.jl | 2 ++ stdlib/REPL/src/TerminalMenus/TerminalMenus.jl | 10 ++++++++++ 2 files changed, 12 insertions(+) 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/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 From 6ad6a8f1e8b960d8ecb114a03e8e0eebf712abfb Mon Sep 17 00:00:00 2001 From: Octogonapus Date: Mon, 5 Aug 2024 16:01:02 -0400 Subject: [PATCH 064/115] Delete broken and unhelpful const mutation example from docs (#55182) --- doc/src/manual/variables-and-scoping.md | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) 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}: From d1b1a5dd254e127edc994076cce61ae1cca16979 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Mon, 5 Aug 2024 16:46:54 -0400 Subject: [PATCH 065/115] inference: fix missing LimitedAccuracy markers (#55362) If the LimitedAccuracy was supposed to resolve against the top-most frame (or hypothetically a non-InferenceState frame), it would not have a parentframe, preventing it from reaching the subsequent poison_callstack line that is required for reliable inference (avoiding caching bad results). This should restore the original intent of this code (pre #48913) --- base/compiler/abstractinterpretation.jl | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index 6a7d90a7bcb21..e3e3502d66173 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -698,13 +698,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 From 1b32fa6825739ab68542f6ea476b09931f77ec40 Mon Sep 17 00:00:00 2001 From: Michael Abbott <32575566+mcabbott@users.noreply.github.com> Date: Mon, 5 Aug 2024 22:39:30 -0400 Subject: [PATCH 066/115] Compact printing for `Adjoint` vectors, and `Diagonal` (#40722) This changes the compact printing to preserve more information -- an adjoint vector is not quite a matrix, and Diagonal wastes a lot of space: ```julia julia> (Diagonal(1:4), [5,6,7]', transpose(8:10)) # before ([1 0 0 0; 0 2 0 0; 0 0 3 0; 0 0 0 4], [5 6 7], [8 9 10]) julia> (Diagonal(1:4), [5,6,7]', transpose(8:10)) # after (Diagonal(1:4), adjoint([5, 6, 7]), transpose(8:10)) ``` Would have been better to do at the same time as 1.6's other printing changes, I guess. --------- Co-authored-by: Jishnu Bhattacharya --- base/abstractarray.jl | 2 +- stdlib/LinearAlgebra/src/adjtrans.jl | 10 ++++++++++ stdlib/LinearAlgebra/src/diagonal.jl | 5 +++++ stdlib/LinearAlgebra/test/adjtrans.jl | 5 +++++ stdlib/LinearAlgebra/test/diagonal.jl | 5 +++++ 5 files changed, 26 insertions(+), 1 deletion(-) diff --git a/base/abstractarray.jl b/base/abstractarray.jl index 2fbae2c423196..40e36ce15f6ed 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -1921,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}: 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/diagonal.jl b/stdlib/LinearAlgebra/src/diagonal.jl index 9cd13b4d26f00..89202e66597f8 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 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/diagonal.jl b/stdlib/LinearAlgebra/test/diagonal.jl index e1fc9afa5ad2e..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()) From b0a8024a4598f60f72a0799b3b60a29383188523 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mos=C3=A8=20Giordano?= Date: Tue, 6 Aug 2024 10:46:41 +0200 Subject: [PATCH 067/115] [build] Some improvements to the LLVM build system (#55354) ### Elaboration of the issue After #55180 we implicitly require an LLVM built with Zlib support, but compiling Julia with `make USE_BINARYBUILDER_LLVM=0` builds an LLVM without Zlib support, despite the fact we attempt to request it at https://github.com/JuliaLang/julia/blob/996351f5f6651d1508aef3c35c7d37eb22a0fb1e/deps/llvm.mk#L97 This was first identified in #55337. ### Explanation of how configuration of LLVM failed `ZLIB_LIBRARY` must be the path to the zlib library, but we currently set it to the libdir where the library is installed (introduced in #42622): https://github.com/JuliaLang/julia/blob/996351f5f6651d1508aef3c35c7d37eb22a0fb1e/deps/llvm.mk#L97 which is wrong. However, CMake is actually able to find Zlib correctly, but then the check at https://github.com/llvm/llvm-project/blob/46425b8d0fac3c529aa4a716d19abd7032e452f3/llvm/cmake/config-ix.cmake#L139-L141 uses the value of `ZLIB_LIBRARY` to list the Zlib to link for the test, but being `ZLIB_LIBRARY` a directory, CMake doesn't see any valid Zlib and thus tries to run the test without linking any Zlib, and the test silently fails (they're silent only when `LLVM_ENABLE_ZLIB=ON`), resulting in no usable Zlib available, even if found. ### Proposed solution `ZLIB_ROOT` is the only [hint recommended by the CMake module `FindZLIB`](https://cmake.org/cmake/help/latest/module/FindZLIB.html#hints). This PR replaces a broken `ZLIB_LIBRARY` with an appropriate `ZLIB_ROOT`. Also, we set `LLVM_ENABLE_ZLIB=FORCE_ON` which is the only way to make CMake fail loudly if no usable Zlib is available, and avoid going on with a non-usable build. ### Other comments I confirm this fixes #55337 for me, it should likely address https://github.com/JuliaCI/julia-buildkite/issues/373 as well. Also, options `COMPILER_RT_ENABLE_IOS`, `COMPILER_RT_ENABLE_WATCHOS`, `COMPILER_RT_ENABLE_TVOS`, and `HAVE_HISTEDIT_H` don't exist anymore, and they are removed. --- deps/BOLT.mk | 2 +- deps/llvm.mk | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) 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/llvm.mk b/deps/llvm.mk index eddf9b60e38c7..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 From 1e1e710ddd7a7c0fec3c79b69024fa3b7cb2a14c Mon Sep 17 00:00:00 2001 From: William Moses Date: Tue, 6 Aug 2024 05:01:59 -0400 Subject: [PATCH 068/115] AllocOpt: Fix stack lowering where alloca continas boxed and unboxed data (#55306) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Valentin Churavy Co-authored-by: Mosè Giordano Co-authored-by: Gabriel Baraldi --- src/llvm-alloc-helpers.cpp | 10 ++++++++- src/llvm-alloc-helpers.h | 7 ++++++ src/llvm-alloc-opt.cpp | 15 +++++++++++++ test/llvmpasses/alloc-opt-bits.ll | 37 +++++++++++++++++++++++++++++++ 4 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 test/llvmpasses/alloc-opt-bits.ll 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/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() From 0717a9454d7eb2275575d22f97962d9d9f1e95e2 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Tue, 6 Aug 2024 06:53:10 -0400 Subject: [PATCH 069/115] Revert "better type inference for several functions taking `NTuple` args" (#55375) Reverts JuliaLang/julia#55124 as this turns out to hurt performance quite a bit Closes #55374 --- base/essentials.jl | 8 +------- base/ntuple.jl | 2 +- base/tuple.jl | 16 +++------------- test/tuple.jl | 7 ------- 4 files changed, 5 insertions(+), 28 deletions(-) diff --git a/base/essentials.jl b/base/essentials.jl index 2e76235cba9a6..50017b3d7927d 100644 --- a/base/essentials.jl +++ b/base/essentials.jl @@ -501,13 +501,7 @@ julia> Base.tail(()) ERROR: ArgumentError: Cannot call tail on an empty tuple. ``` """ -function tail(x::Tuple{Any,Vararg}) - y = argtail(x...)::Tuple - if x isa NTuple # help the type inference - y = y::NTuple - end - y -end +tail(x::Tuple) = argtail(x...) tail(::Tuple{}) = throw(ArgumentError("Cannot call tail on an empty tuple.")) function unwrap_unionall(@nospecialize(a)) diff --git a/base/ntuple.jl b/base/ntuple.jl index 4adab38a8ee82..f81d2686b9764 100644 --- a/base/ntuple.jl +++ b/base/ntuple.jl @@ -95,5 +95,5 @@ end function reverse(t::NTuple{N}) where N ntuple(Val{N}()) do i t[end+1-i] - end::NTuple + end end diff --git a/base/tuple.jl b/base/tuple.jl index 5f74d486e1e69..fc213410cfd7c 100644 --- a/base/tuple.jl +++ b/base/tuple.jl @@ -340,15 +340,9 @@ ERROR: ArgumentError: Cannot call front on an empty tuple. """ function front(t::Tuple) @inline - if t === () - throw(ArgumentError("Cannot call front on an empty tuple.")) - end - r = _front(t...)::Tuple - if t isa NTuple # help the type inference - r = r::NTuple - end - r + _front(t...) end +_front() = throw(ArgumentError("Cannot call front on an empty tuple.")) _front(v) = () function _front(v, t...) @inline @@ -705,9 +699,5 @@ function circshift(x::Tuple{Any,Any,Any,Vararg{Any,N}}, shift::Integer) where {N @inline len = N + 3 j = mod1(shift, len) - y = ntuple(k -> getindex(x, k-j+ifelse(k>j,0,len)), Val(len))::Tuple - if x isa NTuple # help the type inference - y = y::NTuple - end - y + ntuple(k -> getindex(x, k-j+ifelse(k>j,0,len)), Val(len))::Tuple end diff --git a/test/tuple.jl b/test/tuple.jl index 59897c8adfdb2..b1894bd2bb6ce 100644 --- a/test/tuple.jl +++ b/test/tuple.jl @@ -845,10 +845,3 @@ end end end end - -@testset "abstract return type inference for homogeneous tuples" begin - @test NTuple == Core.Compiler.return_type(Base.tail, Tuple{NTuple}) - @test NTuple == Core.Compiler.return_type(Base.front, Tuple{NTuple}) - @test NTuple == Core.Compiler.return_type(reverse, Tuple{NTuple}) - @test NTuple == Core.Compiler.return_type(circshift, Tuple{NTuple,Int}) -end From 73777606489c1bd2a2851e73f85aed6224761f9b Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Tue, 6 Aug 2024 15:14:30 +0000 Subject: [PATCH 070/115] Fuse complex conversion with function application for symmetric (#55391) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This avoids allocating an intermediate array, which reduces allocation slightly. ```julia julia> S = Symmetric(diagm(0=>-rand(100))); julia> @btime $S^0.2; 479.196 μs (25 allocations: 560.20 KiB) # nightly v"1.12.0-DEV.994" 478.213 μs (23 allocations: 558.58 KiB) # This PR ``` --- stdlib/LinearAlgebra/src/symmetric.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 From f94fe63c46d6dd860a633d429003dc5be9c472e4 Mon Sep 17 00:00:00 2001 From: "Viral B. Shah" Date: Tue, 6 Aug 2024 11:14:58 -0400 Subject: [PATCH 071/115] Disable printing of message about including GPL libs in libsuitesparse.mk (#55387) https://github.com/JuliaLang/julia/pull/54240/files#r1704655126 Co-authored-by: Viral B. Shah --- deps/libsuitesparse.mk | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/deps/libsuitesparse.mk b/deps/libsuitesparse.mk index d840a7b298e17..85b2c23473a18 100644 --- a/deps/libsuitesparse.mk +++ b/deps/libsuitesparse.mk @@ -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* From 308cd7b61267c4e4dbbd48cc979948f3675e8fc1 Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Tue, 6 Aug 2024 16:42:29 +0000 Subject: [PATCH 072/115] LAPACK: return union of tuples in gees and trsen (#55353) This simplifies the return type from a `Tuple` with a `Union` field to a `Union` of `Tuple`s. --- stdlib/LinearAlgebra/src/lapack.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stdlib/LinearAlgebra/src/lapack.jl b/stdlib/LinearAlgebra/src/lapack.jl index 6d1d871ed85fd..97dff0031329b 100644 --- a/stdlib/LinearAlgebra/src/lapack.jl +++ b/stdlib/LinearAlgebra/src/lapack.jl @@ -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) From 09e5c40173297365cf09a09aec876d0ba6493958 Mon Sep 17 00:00:00 2001 From: Simeon David Schaub Date: Tue, 6 Aug 2024 19:03:54 +0200 Subject: [PATCH 073/115] fix #55389: type-unstable `join` (#55395) --- base/strings/io.jl | 5 +++-- test/strings/io.jl | 5 +++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/base/strings/io.jl b/base/strings/io.jl index c88b7ac939c8d..acbd945c8e137 100644 --- a/base/strings/io.jl +++ b/base/strings/io.jl @@ -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)) diff --git a/test/strings/io.jl b/test/strings/io.jl index 79e11d8cf5184..209844580b3cd 100644 --- a/test/strings/io.jl +++ b/test/strings/io.jl @@ -344,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 From fb4e4e5bddf5896bf6c8596026ecd275e599b9af Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Tue, 6 Aug 2024 19:04:06 +0000 Subject: [PATCH 074/115] Don't read destination indices when copying structured matrices (#55322) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following regression introduced in v1.11 ```julia julia> using LinearAlgebra julia> D = Diagonal(rand(4)); julia> T = Tridiagonal(Vector{BigFloat}(undef, 3), Vector{BigFloat}(undef, 4), Vector{BigFloat}(undef, 3)) 4×4 Tridiagonal{BigFloat, Vector{BigFloat}}: #undef #undef ⋅ ⋅ #undef #undef #undef ⋅ ⋅ #undef #undef #undef ⋅ ⋅ #undef #undef julia> copyto!(T, D) ERROR: UndefRefError: access to undefined reference Stacktrace: [1] getindex @ ./essentials.jl:907 [inlined] [2] _broadcast_getindex @ ./broadcast.jl:644 [inlined] [3] _getindex @ ./broadcast.jl:675 [inlined] [4] _broadcast_getindex @ ./broadcast.jl:650 [inlined] [5] getindex @ ./broadcast.jl:610 [inlined] [6] macro expansion @ ./broadcast.jl:973 [inlined] [7] macro expansion @ ./simdloop.jl:77 [inlined] [8] copyto! @ ./broadcast.jl:972 [inlined] [9] copyto! @ ./broadcast.jl:925 [inlined] [10] materialize! @ ./broadcast.jl:883 [inlined] [11] materialize! @ ./broadcast.jl:880 [inlined] [12] _copyto_banded!(T::Tridiagonal{BigFloat, Vector{BigFloat}}, D::Diagonal{Float64, Vector{Float64}}) @ LinearAlgebra ~/.julia/juliaup/julia-nightly/share/julia/stdlib/v1.12/LinearAlgebra/src/special.jl:323 [13] copyto!(dest::Tridiagonal{BigFloat, Vector{BigFloat}}, src::Diagonal{Float64, Vector{Float64}}) @ LinearAlgebra ~/.julia/juliaup/julia-nightly/share/julia/stdlib/v1.12/LinearAlgebra/src/special.jl:315 [14] top-level scope @ REPL[4]:1 ``` After this PR ```julia julia> copyto!(T, D) 4×4 Tridiagonal{BigFloat, Vector{BigFloat}}: 0.909968 0.0 ⋅ ⋅ 0.0 0.193341 0.0 ⋅ ⋅ 0.0 0.194794 0.0 ⋅ ⋅ 0.0 0.506905 ``` The current implementation used an optimization that may not be applicable for non-isbits types, and this PR ensures that we always read from the source and write to the destination. --- stdlib/LinearAlgebra/src/bidiag.jl | 2 +- stdlib/LinearAlgebra/src/special.jl | 14 +++++++------- stdlib/LinearAlgebra/src/tridiag.jl | 2 +- stdlib/LinearAlgebra/test/special.jl | 17 +++++++++-------- stdlib/LinearAlgebra/test/tridiag.jl | 2 +- 5 files changed, 19 insertions(+), 18 deletions(-) diff --git a/stdlib/LinearAlgebra/src/bidiag.jl b/stdlib/LinearAlgebra/src/bidiag.jl index 0caaec02b5056..24958422015ab 100644 --- a/stdlib/LinearAlgebra/src/bidiag.jl +++ b/stdlib/LinearAlgebra/src/bidiag.jl @@ -305,7 +305,7 @@ function _copyto_banded!(A::Bidiagonal, B::Bidiagonal) 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 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/tridiag.jl b/stdlib/LinearAlgebra/src/tridiag.jl index 2ff688f4b4ed1..e217425402df9 100644 --- a/stdlib/LinearAlgebra/src/tridiag.jl +++ b/stdlib/LinearAlgebra/src/tridiag.jl @@ -1040,7 +1040,7 @@ 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 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/tridiag.jl b/stdlib/LinearAlgebra/test/tridiag.jl index 5dc1d01e850d8..41a28631b27a0 100644 --- a/stdlib/LinearAlgebra/test/tridiag.jl +++ b/stdlib/LinearAlgebra/test/tridiag.jl @@ -808,7 +808,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]] From 22f55804b9c0da372c8a5f8819732b034b442b51 Mon Sep 17 00:00:00 2001 From: Markus Hauru Date: Tue, 6 Aug 2024 22:28:51 +0100 Subject: [PATCH 075/115] Deprecate conflicting @testset arguments (#55174) Currently `@testset` allows specifying multiple descriptions and testset types, and only the last one will take effect. The others will be silently ignored. This PR starts printing deprecation warnings whenever such conflicting arguments are provided. --- stdlib/Test/src/Test.jl | 10 ++++++++++ stdlib/Test/test/runtests.jl | 10 ++++++++++ 2 files changed, 20 insertions(+) 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 From e4678ab775dadc95dd8bb050637817e449ee7300 Mon Sep 17 00:00:00 2001 From: Miles Cranmer Date: Tue, 6 Aug 2024 17:43:27 -0400 Subject: [PATCH 076/115] Increase default stack size limit on 64-bit systems (#55185) This increases the default stack size limit on 64-bit systems from 4 MB to 8 MB, matching glibc and typical modern Linux and macOS machines, as well as the stack size limit of the root Julia process. --- src/options.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From 016d035cd2678d3af90601ca2aa3aed35d50721d Mon Sep 17 00:00:00 2001 From: DilumAluthgeBot <43731525+DilumAluthgeBot@users.noreply.github.com> Date: Tue, 6 Aug 2024 19:48:10 -0400 Subject: [PATCH 077/115] =?UTF-8?q?=F0=9F=A4=96=20[master]=20Bump=20the=20?= =?UTF-8?q?Pkg=20stdlib=20from=20e4a6723bf=20to=207aef1f044=20(#55399)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Pkg-7aef1f044f3483e8b07d33fb4cfe918be554de69.tar.gz/md5 | 1 + .../Pkg-7aef1f044f3483e8b07d33fb4cfe918be554de69.tar.gz/sha512 | 1 + .../Pkg-e4a6723bf3074764ff9266e5e13dfea501431b33.tar.gz/md5 | 1 - .../Pkg-e4a6723bf3074764ff9266e5e13dfea501431b33.tar.gz/sha512 | 1 - stdlib/Pkg.version | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 deps/checksums/Pkg-7aef1f044f3483e8b07d33fb4cfe918be554de69.tar.gz/md5 create mode 100644 deps/checksums/Pkg-7aef1f044f3483e8b07d33fb4cfe918be554de69.tar.gz/sha512 delete mode 100644 deps/checksums/Pkg-e4a6723bf3074764ff9266e5e13dfea501431b33.tar.gz/md5 delete mode 100644 deps/checksums/Pkg-e4a6723bf3074764ff9266e5e13dfea501431b33.tar.gz/sha512 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/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 From b3a62b4c30f718e7f0f226342abb0b636b91f3b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mos=C3=A8=20Giordano?= Date: Wed, 7 Aug 2024 03:16:44 +0200 Subject: [PATCH 078/115] Restore cmdlineargs tests on non-Windows platforms (#55368) --- test/cmdlineargs.jl | 64 ++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 35 deletions(-) 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 From b43e24715869b15eb8a9f6e669a03f4722bfb32f Mon Sep 17 00:00:00 2001 From: "Steven G. Johnson" Date: Wed, 7 Aug 2024 07:48:13 -0400 Subject: [PATCH 079/115] optimized textwidth(::Char) for ASCII (#55398) --- base/strings/unicode.jl | 9 +++++++++ test/strings/util.jl | 14 ++++++++++++++ 2 files changed, 23 insertions(+) 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/test/strings/util.jl b/test/strings/util.jl index 59638dc3b9ca6..e5db9bd03ae8e 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" From bd582f78ed3ecd3950b676e14bf0a7a64092aa3d Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Wed, 7 Aug 2024 16:42:30 +0000 Subject: [PATCH 080/115] Accept axes in Base.checkdims_perm (#55403) Since `checkdims_perm` only checks the axes of the arrays that are passed to it, this PR adds a method that accepts the axes as arguments instead of the arrays. This will avoid having to specialize on array types. An example of an improvement: On master ```julia julia> using LinearAlgebra julia> D = Diagonal(zeros(1)); julia> Dv = Diagonal(view(zeros(1),:)); julia> @time @eval permutedims(D, (2,1)); 0.016841 seconds (13.68 k allocations: 680.672 KiB, 51.37% compilation time) julia> @time @eval permutedims(Dv, (2,1)); 0.009303 seconds (11.24 k allocations: 564.203 KiB, 97.79% compilation time) ``` This PR ```julia julia> @time @eval permutedims(D, (2,1)); 0.016837 seconds (13.42 k allocations: 667.438 KiB, 51.05% compilation time) julia> @time @eval permutedims(Dv, (2,1)); 0.009076 seconds (6.59 k allocations: 321.156 KiB, 97.46% compilation time) ``` The allocations are lower in the second call. I've retained the original method as well, as some packages seem to be using it. This now forwards the axes to the new method. --- base/multidimensional.jl | 9 ++++----- base/permuteddimsarray.jl | 2 +- stdlib/LinearAlgebra/src/bidiag.jl | 2 +- stdlib/LinearAlgebra/src/diagonal.jl | 2 +- stdlib/LinearAlgebra/src/tridiag.jl | 4 ++-- 5 files changed, 9 insertions(+), 10 deletions(-) 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/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/stdlib/LinearAlgebra/src/bidiag.jl b/stdlib/LinearAlgebra/src/bidiag.jl index 24958422015ab..adb5f8c51bf47 100644 --- a/stdlib/LinearAlgebra/src/bidiag.jl +++ b/stdlib/LinearAlgebra/src/bidiag.jl @@ -287,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}) diff --git a/stdlib/LinearAlgebra/src/diagonal.jl b/stdlib/LinearAlgebra/src/diagonal.jl index 89202e66597f8..77459f7cca520 100644 --- a/stdlib/LinearAlgebra/src/diagonal.jl +++ b/stdlib/LinearAlgebra/src/diagonal.jl @@ -745,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/tridiag.jl b/stdlib/LinearAlgebra/src/tridiag.jl index e217425402df9..c14ed5690198c 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))...) @@ -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))...)) From c767032b8ffec975cf2335105de082a6e6079c31 Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Thu, 8 Aug 2024 02:12:08 +0000 Subject: [PATCH 081/115] Improve performance in `Bidiagonal` times `Diagonal` (#55175) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds specialized methods to improve performance, and avoid allocations that were arising currently from the fallback tridiagonal implementations. ```julia julia> using LinearAlgebra, BenchmarkTools julia> n = 10000; B = Bidiagonal(rand(n), rand(n-1), :U); D = Diagonal(rand(size(B,1))); C = similar(B, size(B)); julia> @btime mul!($C, $B, $D); 25.552 ms (3 allocations: 78.19 KiB) # v"1.12.0-DEV.870" 25.559 ms (0 allocations: 0 bytes) # This PR julia> C = similar(B); julia> @btime mul!($C, $B, $D); 23.551 μs (3 allocations: 78.19 KiB) # v"1.12.0-DEV.870" 7.123 μs (0 allocations: 0 bytes) # This PR, specialized method ``` --- stdlib/LinearAlgebra/src/bidiag.jl | 168 +++++++++++++++++++++++++--- stdlib/LinearAlgebra/test/bidiag.jl | 39 ++++++- test/testhelpers/SizedArrays.jl | 4 + 3 files changed, 192 insertions(+), 19 deletions(-) diff --git a/stdlib/LinearAlgebra/src/bidiag.jl b/stdlib/LinearAlgebra/src/bidiag.jl index adb5f8c51bf47..5aa4314c9ae51 100644 --- a/stdlib/LinearAlgebra/src/bidiag.jl +++ b/stdlib/LinearAlgebra/src/bidiag.jl @@ -299,6 +299,13 @@ 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 @@ -307,10 +314,7 @@ function _copyto_banded!(A::Bidiagonal, B::Bidiagonal) elseif iszero(B.ev) # diagonal source 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 @@ -620,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) @@ -629,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) @@ -781,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/test/bidiag.jl b/stdlib/LinearAlgebra/test/bidiag.jl index 3c99d0d3b6f5e..e19d890237a26 100644 --- a/stdlib/LinearAlgebra/test/bidiag.jl +++ b/stdlib/LinearAlgebra/test/bidiag.jl @@ -942,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)) @@ -966,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) 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}} From 07f563ea05cb5cce2661d1e5f8a0a6218089689f Mon Sep 17 00:00:00 2001 From: Zentrik Date: Thu, 8 Aug 2024 13:07:38 +0100 Subject: [PATCH 082/115] Fix unterminated strings in bolt makefiles (#55410) --- contrib/bolt/Makefile | 2 +- contrib/pgo-lto-bolt/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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/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 From e4398360c33b6065e550b6b5b663543c1e497a57 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Thu, 8 Aug 2024 09:41:59 -0400 Subject: [PATCH 083/115] add `rtruncate`, `ltruncate`, `ctruncate` for truncating strings in terms of `textwidth` (#55351) Co-authored-by: Timothy Co-authored-by: Steven G. Johnson <2913679+stevengj@users.noreply.github.com> --- NEWS.md | 1 + base/exports.jl | 3 + base/strings/util.jl | 148 ++++++++++++++++++++++++++++++++++++++++ doc/src/base/strings.md | 3 + test/strings/util.jl | 46 +++++++++++++ 5 files changed, 201 insertions(+) diff --git a/NEWS.md b/NEWS.md index 2e9b32befe342..c4e46acca164e 100644 --- a/NEWS.md +++ b/NEWS.md @@ -102,6 +102,7 @@ New library features 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 ------------------------ diff --git a/base/exports.jl b/base/exports.jl index dbe12f933e597..daba9a010a9e6 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -596,6 +596,7 @@ export codepoint, codeunit, codeunits, + ctruncate, digits, digits!, eachsplit, @@ -620,6 +621,7 @@ export join, lpad, lstrip, + ltruncate, ncodeunits, ndigits, nextind, @@ -632,6 +634,7 @@ export rpad, rsplit, rstrip, + rtruncate, split, string, strip, 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/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/test/strings/util.jl b/test/strings/util.jl index e5db9bd03ae8e..ae16e24f4ea8b 100644 --- a/test/strings/util.jl +++ b/test/strings/util.jl @@ -67,6 +67,52 @@ end @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("") == "" From f0a2a7a0a9438433eb1ac824bd09627ab8fd0586 Mon Sep 17 00:00:00 2001 From: Oscar Smith Date: Thu, 8 Aug 2024 10:51:48 -0400 Subject: [PATCH 084/115] re-add `unsafe_convert` for Reinterpret and Reshaped array (#55226) Fxes https://github.com/JuliaLang/julia/issues/54725 --- base/reinterpretarray.jl | 1 + base/reshapedarray.jl | 1 + test/ccall.jl | 5 ++++- 3 files changed, 6 insertions(+), 1 deletion(-) 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/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) From 30d5a3400077f08a7968f7827912920796c63a7c Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Thu, 8 Aug 2024 11:41:33 -0700 Subject: [PATCH 085/115] inference: remove `throw` block deoptimization completely (#49260) Co-authored-by: Cody Tapscott Co-authored-by: Oscar Smith --- base/compiler/abstractinterpretation.jl | 9 ------ base/compiler/compiler.jl | 3 +- base/compiler/inferencestate.jl | 25 ---------------- base/compiler/optimize.jl | 40 +++++++++++-------------- base/compiler/types.jl | 21 ------------- src/julia.h | 21 +++++++------ stdlib/REPL/src/REPLCompletions.jl | 3 +- test/compiler/AbstractInterpreter.jl | 1 - test/compiler/codegen.jl | 2 +- test/dict.jl | 4 +-- 10 files changed, 33 insertions(+), 96 deletions(-) diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index e3e3502d66173..789b7e6f5a962 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -43,15 +43,6 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f), sv::AbsIntState, max_methods::Int) 𝕃ₚ, 𝕃ᵢ = ipo_lattice(interp), typeinf_lattice(interp) ⊑ₚ, ⊔ₚ, ⊔ᵢ = partialorder(𝕃ₚ), join(𝕃ₚ), join(𝕃ᵢ) - 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 - argtypes = arginfo.argtypes matches = find_method_matches(interp, argtypes, atype; max_methods) if isa(matches, FailedMethodMatch) diff --git a/base/compiler/compiler.jl b/base/compiler/compiler.jl index 9aecdaad51aa5..629641308a217 100644 --- a/base/compiler/compiler.jl +++ b/base/compiler/compiler.jl @@ -184,8 +184,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/inferencestate.jl b/base/compiler/inferencestate.jl index 38011656e41ea..06b038ecb6d2e 100644 --- a/base/compiler/inferencestate.jl +++ b/base/compiler/inferencestate.jl @@ -348,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( @@ -1102,30 +1101,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..9c89e8596d237 100644 --- a/base/compiler/optimize.jl +++ b/base/compiler/optimize.jl @@ -23,31 +23,29 @@ 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 has no users and may be deleted if flags get refined to IR_FLAGS_REMOVABLE -const IR_FLAG_UNUSED = one(UInt32) << 12 +const IR_FLAG_UNUSED = one(UInt32) << 11 -const NUM_IR_FLAGS = 13 # sync with julia.h +const NUM_IR_FLAGS = 12 # sync with julia.h const IR_FLAGS_EFFECTS = IR_FLAG_CONSISTENT | IR_FLAG_EFFECT_FREE | IR_FLAG_NOTHROW | IR_FLAG_TERMINATES | IR_FLAG_NOUB @@ -249,9 +247,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] @@ -1272,7 +1269,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 +1330,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 +1349,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 +1372,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 +1386,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/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/src/julia.h b/src/julia.h index cbe60e78c2d24..2054a434577e7 100644 --- a/src/julia.h +++ b/src/julia.h @@ -276,7 +276,7 @@ typedef union __jl_purity_overrides_t { } _jl_purity_overrides_t; #define NUM_EFFECTS_OVERRIDES 10 -#define NUM_IR_FLAGS 13 +#define NUM_IR_FLAGS 12 // This type describes a single function body typedef struct _jl_code_info_t { @@ -288,16 +288,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 diff --git a/stdlib/REPL/src/REPLCompletions.jl b/stdlib/REPL/src/REPLCompletions.jl index 609a7b4d81bc0..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) 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..cd2702ff0e6aa 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 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 From 1d7b036b7318215b418a369dff700ea2a406ebec Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Thu, 8 Aug 2024 18:24:40 +0000 Subject: [PATCH 086/115] move clamp from math to intfuncs This is a more apt description, since it is not floating point related, and used earlier (such as in IOBuffer). Fixes #55279 --- base/intfuncs.jl | 99 ++++++++++++++++++++++++++++++++++++++++++++++ base/math.jl | 101 +---------------------------------------------- base/missing.jl | 1 + 3 files changed, 101 insertions(+), 100 deletions(-) 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/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") From fc6047bf17e0e6ef13fb487852248017d082d949 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Thu, 8 Aug 2024 18:42:45 +0000 Subject: [PATCH 087/115] copyuntil: reduce over-allocation to start This fits into a 32-byte allocation pool, saving up to 64 bytes when repeatedly reading small chunks of data (e.g. tokenizing a CSV file). In some local `@btime` measurements, this seems to take <10% more time across a range of output lengths. --- base/io.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 From be77f650deb8dbf6496e4bb85e19409a0459f1a5 Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Thu, 8 Aug 2024 14:59:53 -0400 Subject: [PATCH 088/115] improve docs for `collect` and square brackets (#55352) fixes #55350 --------- Co-authored-by: Neven Sajko --- base/abstractarray.jl | 2 ++ base/array.jl | 20 +++++++++++++++++++- base/broadcast.jl | 1 + base/docs/basedocs.jl | 7 +++++-- 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/base/abstractarray.jl b/base/abstractarray.jl index 40e36ce15f6ed..77aae63399ec8 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -3408,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 diff --git a/base/array.jl b/base/array.jl index 008a52abb952e..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)) 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/docs/basedocs.jl b/base/docs/basedocs.jl index 2ed1bd98caa5c..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"]" From f2767570fd5b1f3cfb3f69e8acca22cbb850a386 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Thu, 8 Aug 2024 15:17:34 -0400 Subject: [PATCH 089/115] REPL: disable flaky win32 stacktrace tests (#55408) Disables these tests on win32 that have been flaky on that platform since February at least https://github.com/JuliaLang/julia/issues/53340 --- stdlib/REPL/test/repl.jl | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/stdlib/REPL/test/repl.jl b/stdlib/REPL/test/repl.jl index 6f0c4a5c3d6ba..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 @@ -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") From 32423a8039daeb57ecd7bc26db5476125c0bfb62 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Thu, 8 Aug 2024 15:18:11 -0400 Subject: [PATCH 090/115] handle unbound vars in NTuple fields (#55405) Comparing objects by `==` will happily answer nonsense for malformed type comparisons, such as `unwrap_unionall(A) == A`. Avoid forming that query. Additionally, need to recourse through Vararg when examining type structure to make decisions. Fix #55076 Fix #55189 --- src/builtins.c | 6 ++++++ src/jltypes.c | 6 +++--- test/core.jl | 7 +++++++ 3 files changed, 16 insertions(+), 3 deletions(-) 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/jltypes.c b/src/jltypes.c index fe490d2c45acb..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; } } diff --git a/test/core.jl b/test/core.jl index e765d5a2ab7d7..79373722185b7 100644 --- a/test/core.jl +++ b/test/core.jl @@ -7495,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 From 7e1f0be207b5247a8303549f1aec2c73e79c403e Mon Sep 17 00:00:00 2001 From: Gabriel Baraldi Date: Thu, 8 Aug 2024 16:27:33 -0300 Subject: [PATCH 091/115] codgen: make the Memory GEP an inbounds GEP (#55107) The Julia memory model is always inbounds for GEP. This makes the code in https://github.com/JuliaLang/julia/issues/55090 look almost the same as it did before the change. Locally I wasn't able to reproduce the regression, but given it's vectorized code I suspect it is backend sensitive. Fixes https://github.com/JuliaLang/julia/issues/55090 Co-authored-by: Zentrik --- src/cgutils.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/cgutils.cpp b/src/cgutils.cpp index 08d51f52b613b..3695dc1370050 100644 --- a/src/cgutils.cpp +++ b/src/cgutils.cpp @@ -4286,9 +4286,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; From 1db5cf7bfc965d50ae96fa4b1eb34944731cca21 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Thu, 8 Aug 2024 18:37:08 -0400 Subject: [PATCH 092/115] ml-matches: ensure all methods are included (#55365) Some methods were filtered out based simply on visit order, which was not intentional, with the lim==-1 weak-edges mode. Fix #55231 --- src/gf.c | 2 +- test/ambiguous.jl | 16 ++++++++++++++++ test/core.jl | 2 +- 3 files changed, 18 insertions(+), 2 deletions(-) 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/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/core.jl b/test/core.jl index 79373722185b7..4cbb872ce4e50 100644 --- a/test/core.jl +++ b/test/core.jl @@ -7572,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,) From 57aef91b4776e3bc07a813989ab56475b459ab9c Mon Sep 17 00:00:00 2001 From: Nathan Zimmerberg <39104088+nhz2@users.noreply.github.com> Date: Thu, 8 Aug 2024 18:56:56 -0400 Subject: [PATCH 093/115] Make `mv` more atomic by trying rename before deleting `dst` (#55384) As noted in https://github.com/JuliaLang/julia/issues/41584 and https://discourse.julialang.org/t/safe-overwriting-of-files/117758/3 `mv` is usually expected to be "best effort atomic". Currently calling `mv` with `force=true` calls `checkfor_mv_cp_cptree(src, dst, "moving"; force=true)` before renaming. `checkfor_mv_cp_cptree` will delete `dst` if exists and isn't the same as `src`. If `dst` is an existing file and julia stops after deleting `dst` but before doing the rename, `dst` will be removed but will not be replaced with `src`. This PR changes `mv` with `force=true` to first try rename, and only delete `dst` if that fails. Assuming file system support and the first rename works, julia stopping will not lead to `dst` being removed without being replaced. This also replaces a stopgap solution from https://github.com/JuliaLang/julia/pull/36638#discussion_r453820564 --- base/file.jl | 77 ++++++++++++++++++++++++++++++++++++++++------ base/loading.jl | 6 ++-- test/file.jl | 2 +- test/filesystem.jl | 2 +- 4 files changed, 74 insertions(+), 13 deletions(-) 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/loading.jl b/base/loading.jl index c273e4505701f..eb467d9cc0bd4 100644 --- a/base/loading.jl +++ b/base/loading.jl @@ -3047,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 @@ -3066,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 diff --git a/test/file.jl b/test/file.jl index f82b2a0fd8f39..005c765e08b90 100644 --- a/test/file.jl +++ b/test/file.jl @@ -1031,7 +1031,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 From e7e8768a77548250d6a06a9fcd35086a0e876ddb Mon Sep 17 00:00:00 2001 From: Alex Arslan Date: Thu, 8 Aug 2024 16:44:30 -0700 Subject: [PATCH 094/115] Vendor the terminfo database for use with base/terminfo.jl (#55411) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds the `terminfo` database to `deps/`, providing a better user experience on systems that don't have `terminfo` on the system by default. The database is built using BinaryBuilder but is not actually platform-specific (it's built for `AnyPlatform`) and as such, this fetches the artifact directly rather than adding a new JLL to stdlib, and it requires no compilation. A build flag, `WITH_TERMINFO`, is added here and assumed true by default, allowing users to set `WITH_TERMINFO=0` in Make.user to avoid bundling `terminfo` should they want to do so. The lookup policy for `terminfo` entries is still compliant with what's described in `terminfo(5)`; the bundled directory is taken to be the first "compiled in" location, i.e. prepended to `@TERMINFO_DIRS@`. This allows any user settings that exist locally, such as custom entries or locations, to take precedence. Fixes #55274 Co-authored-by: Mosè Giordano --- Makefile | 4 +++ NEWS.md | 4 +++ base/terminfo.jl | 11 +++++++- deps/Makefile | 8 +++++- deps/checksums/terminfo | 2 ++ deps/terminfo.mk | 43 ++++++++++++++++++++++++++++++ deps/terminfo.version | 3 +++ stdlib/REPL/test/precompilation.jl | 7 +++-- 8 files changed, 78 insertions(+), 4 deletions(-) create mode 100644 deps/checksums/terminfo create mode 100644 deps/terminfo.mk create mode 100644 deps/terminfo.version 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 c4e46acca164e..4bbe7645165dd 100644 --- a/NEWS.md +++ b/NEWS.md @@ -171,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/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/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/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/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/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) From ac9558c265b53cb3b3569e37be898df9d91d5ce8 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Fri, 9 Aug 2024 07:07:31 -0400 Subject: [PATCH 095/115] codegen: move undef freeze before promotion point (#55428) Fixes #55396 --- src/cgutils.cpp | 10 ++++++++-- test/compiler/codegen.jl | 10 ++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/cgutils.cpp b/src/cgutils.cpp index 3695dc1370050..0969f78f10bb4 100644 --- a/src/cgutils.cpp +++ b/src/cgutils.cpp @@ -3947,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); } @@ -4104,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) diff --git a/test/compiler/codegen.jl b/test/compiler/codegen.jl index cd2702ff0e6aa..c74dfbb29d3dd 100644 --- a/test/compiler/codegen.jl +++ b/test/compiler/codegen.jl @@ -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 From 2727e36a13431c1e7e7e464b2f0b8af0db149198 Mon Sep 17 00:00:00 2001 From: Gabriel Baraldi Date: Fri, 9 Aug 2024 10:59:51 -0300 Subject: [PATCH 096/115] Remove deprecated non string API for LLVM pass pipeline and parse all options (#55407) This technically removes the option for Oz in julia but it doesn't actually do what one wants. This removes an API currently used by Enzyme.jl and AllocCheck.jl but given that LLVM.jl doesn't support this API anymore that seems fine. @wsmoses @maleadt Do we want the replacement for this (a function that parses the PipelineConfig struct) to live in LLVM.jl or GPUCompiler.jl ? --- src/codegen-stubs.c | 2 -- src/jl_exported_funcs.inc | 1 - src/pipeline.cpp | 67 +++++--------------------------------- test/llvmpasses/parsing.ll | 3 ++ 4 files changed, 11 insertions(+), 62 deletions(-) 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/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/pipeline.cpp b/src/pipeline.cpp index e01645cc1f154..236be179e12c9 100644 --- a/src/pipeline.cpp +++ b/src/pipeline.cpp @@ -609,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 @@ -865,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/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 From c3d0d67ac424c889fd7f24552a557c3a7ea8f1e6 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Sat, 10 Aug 2024 00:33:43 +0900 Subject: [PATCH 097/115] inference: follow up #49260, remove no longer necessary functions (#55430) --- base/compiler/inferencestate.jl | 66 --------------------------------- 1 file changed, 66 deletions(-) diff --git a/base/compiler/inferencestate.jl b/base/compiler/inferencestate.jl index 06b038ecb6d2e..87647628f772e 100644 --- a/base/compiler/inferencestate.jl +++ b/base/compiler/inferencestate.jl @@ -517,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 From 18340a3eb40758f5c21428c9c03b3f2b696f475d Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Fri, 9 Aug 2024 19:47:20 +0200 Subject: [PATCH 098/115] `stale_cachefile`: handle if the expected cache file is missing (#55419) Part of fixing https://github.com/JuliaLang/Pkg.jl/issues/3984 --- base/loading.jl | 8 +++++++- test/precompile.jl | 4 ++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/base/loading.jl b/base/loading.jl index eb467d9cc0bd4..4dc735f0099d8 100644 --- a/base/loading.jl +++ b/base/loading.jl @@ -3666,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) 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, From 7ec39e71361c835c9ff4e659d0a23f4892f8249f Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Fri, 9 Aug 2024 19:50:58 +0200 Subject: [PATCH 099/115] fix swallowing internal errors in precompilepkgs (#55432) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Testing: - with a package error ``` (SimpleLooper) pkg> precompile Precompiling all packages... ✗ SimpleLooper 0 dependencies successfully precompiled in 2 seconds ERROR: The following 1 direct dependency failed to precompile: SimpleLooper Failed to precompile SimpleLooper [ff33fe5b-d8e3-4cbd-8bd9-3d2408ff8cab] to "/Users/ian/.julia/compiled/v1.12/SimpleLooper/jl_PQArnH". ERROR: LoadError: Stacktrace: [1] error() @ Base ./error.jl:53 ``` - with interrupt ``` (SimpleLooper) pkg> precompile Precompiling all packages... ^C Interrupted: Exiting precompilation... ◒ SimpleLooper 1 dependency had output during precompilation: ┌ SimpleLooper │ [57879] signal 2: Interrupt: 2 │ in expression starting at /Users/ian/Documents/GitHub/SimpleLooper.jl/src/SimpleLooper.jl:2 └ ``` - an internal error simulated in the same scope that https://github.com/JuliaLang/Pkg.jl/issues/3984 was failing to throw from ``` JULIA stdlib/release.image Unhandled Task ERROR: Stacktrace: [1] error() @ Base ./error.jl:53 [2] (::Base.Precompilation.var"#27#65"{Bool, Bool, Vector{Task}, Dict{Tuple{Base.PkgId, Pair{Cmd, Base.CacheFlags}}, String}, Dict{Tuple{Base.PkgId, Pair{Cmd, Base.CacheFlags}}, String}, Base.Event, Base.Event, ReentrantLock, Vector{Tuple{Base.PkgId, Pair{Cmd, Base.CacheFlags}}}, Dict{Tuple{Base.PkgId, Pair{Cmd, Base.CacheFlags}}, String}, Vector{Tuple{Base.PkgId, Pair{Cmd, Base.CacheFlags}}}, Int64, Vector{Base.PkgId}, Dict{Tuple{Base.PkgId, Pair{Cmd, Base.CacheFlags}}, Bool}, Dict{Tuple{Base.PkgId, Pair{Cmd, Base.CacheFlags}}, Base.Event}, Dict{Tuple{Base.PkgId, Pair{Cmd, Base.CacheFlags}}, Bool}, Vector{Base.PkgId}, Dict{Base.PkgId, String}, Dict{Tuple{Base.PkgId, UInt128, String, String}, Bool}, Base.Precompilation.var"#color_string#38"{Bool}, Bool, Base.Semaphore, Bool, String, Vector{String}, Vector{Base.PkgId}, Base.PkgId, Base.CacheFlags, Cmd, Pair{Cmd, Base.CacheFlags}, Tuple{Base.PkgId, Pair{Cmd, Base.CacheFlags}}})() @ Base.Precompilation ./precompilation.jl:819 ``` --- base/precompilation.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/base/precompilation.jl b/base/precompilation.jl index dfaf671a63534..feee394588b19 100644 --- a/base/precompilation.jl +++ b/base/precompilation.jl @@ -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 From 86231ce5763a41a6661d7834a28ad1c37526044a Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Fri, 9 Aug 2024 19:20:42 +0000 Subject: [PATCH 100/115] LinearAlgebra: round-trippable 2-argument show for `Tridiagonal`/`SymTridiagonal` (#55415) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes the displayed form of a `Tridiaognal` and a `SymTridiagonal` valid constructors. ```julia julia> T = Tridiagonal(1:3, 1:4, 1:3) 4×4 Tridiagonal{Int64, UnitRange{Int64}}: 1 1 ⋅ ⋅ 1 2 2 ⋅ ⋅ 2 3 3 ⋅ ⋅ 3 4 julia> show(T) Tridiagonal(1:3, 1:4, 1:3) julia> S = SymTridiagonal(1:4, 1:3) 4×4 SymTridiagonal{Int64, UnitRange{Int64}}: 1 1 ⋅ ⋅ 1 2 2 ⋅ ⋅ 2 3 3 ⋅ ⋅ 3 4 julia> show(S) SymTridiagonal(1:4, 1:3) ``` Displaying the bands has several advantages: firstly, it's briefer than printing the full array, and secondly, it displays the special structure in the bands, if any. E.g.: ```julia julia> T = Tridiagonal(spzeros(3), spzeros(4), spzeros(3)); julia> show(T) Tridiagonal(sparsevec(Int64[], Float64[], 3), sparsevec(Int64[], Float64[], 4), sparsevec(Int64[], Float64[], 3)) ``` It's clear from the displayed form that `T` has sparse bands. A special handling for `SymTridiagonal` matrices is necessary, as the diagonal band is symmetrized. This means: ```julia julia> using StaticArrays julia> m = SMatrix{2,2}(1:4); julia> S = SymTridiagonal(fill(m,3), fill(m,2)) 3×3 SymTridiagonal{SMatrix{2, 2, Int64, 4}, Vector{SMatrix{2, 2, Int64, 4}}}: [1 3; 3 4] [1 3; 2 4] ⋅ [1 2; 3 4] [1 3; 3 4] [1 3; 2 4] ⋅ [1 2; 3 4] [1 3; 3 4] julia> show(S) SymTridiagonal(SMatrix{2, 2, Int64, 4}[[1 3; 3 4], [1 3; 3 4], [1 3; 3 4]], SMatrix{2, 2, Int64, 4}[[1 3; 2 4], [1 3; 2 4]]) ``` The displayed values correspond to the symmetrized band, and not the actual input arguments. I think displaying the symmetrized elements makes more sense here, as this matches the form in the 3-argument `show`. --- stdlib/LinearAlgebra/src/tridiag.jl | 18 ++++++++++++++++++ stdlib/LinearAlgebra/test/tridiag.jl | 16 ++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/stdlib/LinearAlgebra/src/tridiag.jl b/stdlib/LinearAlgebra/src/tridiag.jl index c14ed5690198c..0ba03634d82ad 100644 --- a/stdlib/LinearAlgebra/src/tridiag.jl +++ b/stdlib/LinearAlgebra/src/tridiag.jl @@ -1045,3 +1045,21 @@ function _copyto_banded!(A::SymTridiagonal, B::Tridiagonal) _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/tridiag.jl b/stdlib/LinearAlgebra/test/tridiag.jl index 41a28631b27a0..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 @@ -914,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 From 7e809b0953cd80ce0fa3078dea20e848bc0d7271 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Sat, 10 Aug 2024 00:31:37 -0400 Subject: [PATCH 101/115] compiler: apply more accurate effects to return_type_tfunc (#55338) In extreme cases, the compiler could mark this function for concrete-eval, even though that is illegal unless the compiler has first deleted this instruction. Otherwise the attempt to concrete-eval will re-run the function repeatedly until it hits a StackOverflow. Workaround to fix #55147 @aviatesk You might know how to solve this even better, using post-optimization effect refinements? Since we should actually only apply the refinement of terminates=false => terminates=true (and thus allowing concrete eval) if the optimization occurs, and not just in inference thinks the optimization would be legal. --------- Co-authored-by: Shuhei Kadowaki --- base/boot.jl | 3 +- base/cmd.jl | 2 +- base/compiler/abstractinterpretation.jl | 7 ++-- base/compiler/compiler.jl | 11 +++-- base/compiler/effects.jl | 55 ++++++++++++++++++------- base/compiler/optimize.jl | 30 ++++++++++---- base/compiler/ssair/show.jl | 2 + base/compiler/tfuncs.jl | 20 +++++---- base/compiler/typeinfer.jl | 3 ++ base/essentials.jl | 33 ++++++++++----- base/expr.jl | 25 +++++++++-- src/julia.h | 5 ++- src/method.c | 2 + 13 files changed, 141 insertions(+), 57 deletions(-) diff --git a/base/boot.jl b/base/boot.jl index f7aee9677e2f2..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 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 789b7e6f5a962..90d395600bbde 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -980,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 @@ -2910,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)) diff --git a/base/compiler/compiler.jl b/base/compiler/compiler.jl index 629641308a217..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") 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/optimize.jl b/base/compiler/optimize.jl index 9c89e8596d237..936b604d373a0 100644 --- a/base/compiler/optimize.jl +++ b/base/compiler/optimize.jl @@ -42,13 +42,16 @@ const IR_FLAG_NOUB = one(UInt32) << 8 const IR_FLAG_EFIIMO = one(UInt32) << 9 # This statement is :inaccessiblememonly == INACCESSIBLEMEM_OR_ARGMEMONLY 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) << 11 +const IR_FLAG_UNUSED = one(UInt32) << 12 -const NUM_IR_FLAGS = 12 # sync with julia.h +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 @@ -78,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 @@ -583,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} @@ -647,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 @@ -772,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) 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 b40f65ab3ca1d..9a4c761b4209b 100644 --- a/base/compiler/tfuncs.jl +++ b/base/compiler/tfuncs.jl @@ -2871,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 @@ -2899,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 @@ -2918,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 85bdd881042dc..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 diff --git a/base/essentials.jl b/base/essentials.jl index 50017b3d7927d..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 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/src/julia.h b/src/julia.h index 2054a434577e7..e211f31c6512c 100644 --- a/src/julia.h +++ b/src/julia.h @@ -271,12 +271,13 @@ 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_IR_FLAGS 12 +#define NUM_EFFECTS_OVERRIDES 11 +#define NUM_IR_FLAGS 13 // This type describes a single function body typedef struct _jl_code_info_t { 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 From 2e1235ea6523aac0ef45ac2a4e56eb73ecebd82d Mon Sep 17 00:00:00 2001 From: Haakon Ludvig Langeland Ervik <45243236+haakon-e@users.noreply.github.com> Date: Sat, 10 Aug 2024 15:35:20 -0700 Subject: [PATCH 102/115] Update asyncmap docs to clarify order of outputs (#54974) --- base/asyncmap.jl | 2 ++ 1 file changed, 2 insertions(+) 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. From d3022722fe19ae746f45d4c891ec3996056d02e3 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Sun, 11 Aug 2024 16:13:56 +0200 Subject: [PATCH 103/115] precompilepkgs: Handle when the terminal is very short (#55445) Fixes https://github.com/JuliaLang/Pkg.jl/issues/3935 1.10 counterpart https://github.com/JuliaLang/Pkg.jl/pull/3988 --- base/precompilation.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/precompilation.jl b/base/precompilation.jl index feee394588b19..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 From a3859ed209006aa83c143e169e664b33bbc6414c Mon Sep 17 00:00:00 2001 From: DilumAluthgeBot <43731525+DilumAluthgeBot@users.noreply.github.com> Date: Sun, 11 Aug 2024 21:11:26 -0400 Subject: [PATCH 104/115] =?UTF-8?q?=F0=9F=A4=96=20[master]=20Bump=20the=20?= =?UTF-8?q?JuliaSyntaxHighlighting=20stdlib=20from=20a463611=20to=2004b232?= =?UTF-8?q?3=20(#55464)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stdlib: JuliaSyntaxHighlighting URL: https://github.com/julialang/JuliaSyntaxHighlighting.jl.git Stdlib branch: main Julia branch: master Old commit: a463611 New commit: 04b2323 Julia version: 1.12.0-DEV JuliaSyntaxHighlighting version: 1.12.0 Bump invoked by: @tecosaur Powered by: [BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl) Diff: https://github.com/julialang/JuliaSyntaxHighlighting.jl/compare/a463611e715c9ec546ac8463c38b6890d892e0c8...04b2323c41f6422464c838fe9045700e9ee75e95 ``` $ git log --oneline a463611..04b2323 04b2323 Support a syntax_errors keyword argument 3fba08b Use concrete refs in paren state struct ``` Co-authored-by: Dilum Aluthge --- .../md5 | 1 + .../sha512 | 1 + .../md5 | 1 - .../sha512 | 1 - stdlib/JuliaSyntaxHighlighting.version | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 deps/checksums/JuliaSyntaxHighlighting-04b2323c41f6422464c838fe9045700e9ee75e95.tar.gz/md5 create mode 100644 deps/checksums/JuliaSyntaxHighlighting-04b2323c41f6422464c838fe9045700e9ee75e95.tar.gz/sha512 delete mode 100644 deps/checksums/JuliaSyntaxHighlighting-a463611e715c9ec546ac8463c38b6890d892e0c8.tar.gz/md5 delete mode 100644 deps/checksums/JuliaSyntaxHighlighting-a463611e715c9ec546ac8463c38b6890d892e0c8.tar.gz/sha512 diff --git a/deps/checksums/JuliaSyntaxHighlighting-04b2323c41f6422464c838fe9045700e9ee75e95.tar.gz/md5 b/deps/checksums/JuliaSyntaxHighlighting-04b2323c41f6422464c838fe9045700e9ee75e95.tar.gz/md5 new file mode 100644 index 0000000000000..518e2705544ed --- /dev/null +++ b/deps/checksums/JuliaSyntaxHighlighting-04b2323c41f6422464c838fe9045700e9ee75e95.tar.gz/md5 @@ -0,0 +1 @@ +956fe26df1daca727ec15bfbc175584f diff --git a/deps/checksums/JuliaSyntaxHighlighting-04b2323c41f6422464c838fe9045700e9ee75e95.tar.gz/sha512 b/deps/checksums/JuliaSyntaxHighlighting-04b2323c41f6422464c838fe9045700e9ee75e95.tar.gz/sha512 new file mode 100644 index 0000000000000..786dd666f2927 --- /dev/null +++ b/deps/checksums/JuliaSyntaxHighlighting-04b2323c41f6422464c838fe9045700e9ee75e95.tar.gz/sha512 @@ -0,0 +1 @@ +20c7990134634dd252909dfa2c43f7b77d427a77f1b726eefdc47781fc3ad46152e81e612d4091541ffb32323154cb5a696157cd24d7a71087d5883720e03728 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/stdlib/JuliaSyntaxHighlighting.version b/stdlib/JuliaSyntaxHighlighting.version index 705f16c785a39..b076cfa26b5aa 100644 --- a/stdlib/JuliaSyntaxHighlighting.version +++ b/stdlib/JuliaSyntaxHighlighting.version @@ -1,4 +1,4 @@ JULIASYNTAXHIGHLIGHTING_BRANCH = main -JULIASYNTAXHIGHLIGHTING_SHA1 = a463611e715c9ec546ac8463c38b6890d892e0c8 +JULIASYNTAXHIGHLIGHTING_SHA1 = 04b2323c41f6422464c838fe9045700e9ee75e95 JULIASYNTAXHIGHLIGHTING_GIT_URL := https://github.com/julialang/JuliaSyntaxHighlighting.jl.git JULIASYNTAXHIGHLIGHTING_TAR_URL = https://api.github.com/repos/julialang/JuliaSyntaxHighlighting.jl/tarball/$1 From 9d222b87d77d8a76f806fb296e33916dde8c9411 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mos=C3=A8=20Giordano?= Date: Mon, 12 Aug 2024 03:13:05 +0200 Subject: [PATCH 105/115] [OpenBLAS_jll] Upgrade to v0.3.28 (#55462) Memo to self: * update version number in `stdlib/OpenBLAS_jll/Project.toml` * update version number and sha in `deps/openblas.version` * refresh checksums with `make -f contrib/refresh_checksums.mk -j openblas` See the [release notes of v0.3.28](https://github.com/OpenMathLib/OpenBLAS/releases/tag/v0.3.28). --- deps/checksums/openblas | 188 +++++++++++++++---------------- deps/openblas.version | 6 +- stdlib/OpenBLAS_jll/Project.toml | 2 +- 3 files changed, 98 insertions(+), 98 deletions(-) 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/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/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. From c907192a4ba1ec1c4a2b00303f1b3f19188c4b5e Mon Sep 17 00:00:00 2001 From: DilumAluthgeBot <43731525+DilumAluthgeBot@users.noreply.github.com> Date: Mon, 12 Aug 2024 06:51:19 -0400 Subject: [PATCH 106/115] =?UTF-8?q?=F0=9F=A4=96=20[master]=20Bump=20the=20?= =?UTF-8?q?SparseArrays=20stdlib=20from=20e61663a=20to=2055976a6=20(#55469?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stdlib: SparseArrays URL: https://github.com/JuliaSparse/SparseArrays.jl.git Stdlib branch: main Julia branch: master Old commit: e61663a New commit: 55976a6 Julia version: 1.12.0-DEV SparseArrays version: 1.12.0 Bump invoked by: @ViralBShah Powered by: [BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl) Diff: https://github.com/JuliaSparse/SparseArrays.jl/compare/e61663ad0a79a48906b0b12d53506e731a614ab8...55976a6e4f883a32e3d3658af50c49879b98fce0 ``` $ git log --oneline e61663a..55976a6 55976a6 Keep sparse solvers docs as before (#552) 95fd7ff Missing space in error message (#554) b8a13ef implement in-place `ldiv!` for Cholesky factorization (#547) 1527014 Do not use nested dissection by default. (#550) ``` Co-authored-by: Dilum Aluthge --- .../md5 | 1 + .../sha512 | 1 + .../md5 | 1 - .../sha512 | 1 - stdlib/SparseArrays.version | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 deps/checksums/SparseArrays-55976a6e4f883a32e3d3658af50c49879b98fce0.tar.gz/md5 create mode 100644 deps/checksums/SparseArrays-55976a6e4f883a32e3d3658af50c49879b98fce0.tar.gz/sha512 delete mode 100644 deps/checksums/SparseArrays-e61663ad0a79a48906b0b12d53506e731a614ab8.tar.gz/md5 delete mode 100644 deps/checksums/SparseArrays-e61663ad0a79a48906b0b12d53506e731a614ab8.tar.gz/sha512 diff --git a/deps/checksums/SparseArrays-55976a6e4f883a32e3d3658af50c49879b98fce0.tar.gz/md5 b/deps/checksums/SparseArrays-55976a6e4f883a32e3d3658af50c49879b98fce0.tar.gz/md5 new file mode 100644 index 0000000000000..401900c9f2739 --- /dev/null +++ b/deps/checksums/SparseArrays-55976a6e4f883a32e3d3658af50c49879b98fce0.tar.gz/md5 @@ -0,0 +1 @@ +7b16893f5a49cee4a4d9219afbb57577 diff --git a/deps/checksums/SparseArrays-55976a6e4f883a32e3d3658af50c49879b98fce0.tar.gz/sha512 b/deps/checksums/SparseArrays-55976a6e4f883a32e3d3658af50c49879b98fce0.tar.gz/sha512 new file mode 100644 index 0000000000000..e8f1bc3c4aaaf --- /dev/null +++ b/deps/checksums/SparseArrays-55976a6e4f883a32e3d3658af50c49879b98fce0.tar.gz/sha512 @@ -0,0 +1 @@ +398028ee8f23ee0b4a5144f5dd03d756cd7575a0b806f351d76339e9521830f75c0c96806a3ee5cebe04853feab51c75c7bcdaaa623acc649bc1a24395df5581 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/stdlib/SparseArrays.version b/stdlib/SparseArrays.version index 7c99b8ba52d7c..2dc7bd8f5b3b9 100644 --- a/stdlib/SparseArrays.version +++ b/stdlib/SparseArrays.version @@ -1,4 +1,4 @@ SPARSEARRAYS_BRANCH = main -SPARSEARRAYS_SHA1 = e61663ad0a79a48906b0b12d53506e731a614ab8 +SPARSEARRAYS_SHA1 = 55976a6e4f883a32e3d3658af50c49879b98fce0 SPARSEARRAYS_GIT_URL := https://github.com/JuliaSparse/SparseArrays.jl.git SPARSEARRAYS_TAR_URL = https://api.github.com/repos/JuliaSparse/SparseArrays.jl/tarball/$1 From cf4c30accd92755bc39d52364ae6549c490a4bc8 Mon Sep 17 00:00:00 2001 From: Mark Kittisopikul Date: Mon, 12 Aug 2024 09:10:03 -0400 Subject: [PATCH 107/115] Add push! implementation for AbstractArray depending only on resize! (#55470) Fix #55459 In Julia 1.10, `push!` and `append!` would be functional for `AbstractVector` implementations if `resize!` and `setindex!` were defined. As of #51903 by @vtjnash as in Julia 1.11.0-rc2, `append!` now depends on an implementation of `sizehint!` and `push!`. Since `push!` also depends on `append!`, a stack overflow situation can easily be created. To avoid this, this pull request defines the following * Add generic versions of `push!(a::AbstractVector, x)` which do not depend on `append!` * Add default implementation of `sizehint!` that is a no-op The implementation of `push!(a::AbstractVector, x)` is a generic version based on the implementation of `push!(a::Vector, x)` without depending on internals. # Example for SimpleArray Consider the `SimpleArray` example from test/abstractarray.jl: ```julia mutable struct SimpleArray{T} <: AbstractVector{T} els::Vector{T} end Base.size(sa::SimpleArray) = size(sa.els) Base.getindex(sa::SimpleArray, idx...) = getindex(sa.els, idx...) Base.setindex!(sa::SimpleArray, v, idx...) = setindex!(sa.els, v, idx...) Base.resize!(sa::SimpleArray, n) = resize!(sa.els, n) Base.copy(sa::SimpleArray) = SimpleArray(copy(sa.els)) ``` Note that `setindex!` and `resize!` are implemented for `SimpleArray`. ## Julia 1.10.4: push! is functional On Julia 1.10.4, `push!` has a functional implementation for `SimpleArray` ```julia-repl julia> push!(SimpleArray{Int}(zeros(Int,5)), 6) 6-element SimpleArray{Int64}: 0 0 0 0 0 6 ``` ## Julia 1.11.0-rc2 and nightly: push! requires sizehint! and is prone to stack overflow Before this pull request, on Julia 1.11.0-rc2 and nightly, `push!` fails for want of `sizehint!`. ```julia-repl julia> push!(SimpleArray{Int}(zeros(Int,5)), 6) ERROR: MethodError: no method matching sizehint!(::SimpleArray{Int64}, ::Int64) The function `sizehint!` exists, but no method is defined for this combination of argument types. ... ``` After implementing `sizehint!`, `push!` still fails with a stack overflow. ```julia-repl julia> Base.sizehint!(a::SimpleArray, x) = a julia> push!(SimpleArray{Int}(zeros(Int, 5)), 6) Warning: detected a stack overflow; program state may be corrupted, so further execution might be unreliable. ERROR: StackOverflowError: Stacktrace: [1] _append! @ ./array.jl:1344 [inlined] [2] append! @ ./array.jl:1335 [inlined] [3] push!(a::SimpleArray{Int64}, iter::Int64) @ Base ./array.jl:1336 --- the above 3 lines are repeated 79982 more times --- [239950] _append! @ ./array.jl:1344 [inlined] [239951] append! @ ./array.jl:1335 [inlined] ``` This is because the new implementation of `append!` depends on `push!`. ## After this pull request, push! is functional. After this pull request, there is a functional `push!` for `SimpleArray` again as in Julia 1.10.4: ```julia-repl julia> push!(SimpleArray{Int}(zeros(Int, 5), 6) 6-element SimpleArray{Int64}: 0 0 0 0 0 6 ``` --- base/abstractarray.jl | 32 ++++++++++++++++++++++++++++++++ test/abstractarray.jl | 9 +++++++++ 2 files changed, 41 insertions(+) diff --git a/base/abstractarray.jl b/base/abstractarray.jl index 77aae63399ec8..3f8886e14940c 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -3525,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) @@ -3532,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/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] From a23aee8c66aaf2c2b35ecb63fe938ae8519f49d9 Mon Sep 17 00:00:00 2001 From: DilumAluthgeBot <43731525+DilumAluthgeBot@users.noreply.github.com> Date: Mon, 12 Aug 2024 12:20:03 -0400 Subject: [PATCH 108/115] =?UTF-8?q?=F0=9F=A4=96=20[master]=20Bump=20the=20?= =?UTF-8?q?StyledStrings=20stdlib=20from=20d7496d2=20to=20f6035eb=20(#5546?= =?UTF-8?q?1)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stdlib: StyledStrings URL: https://github.com/JuliaLang/StyledStrings.jl.git Stdlib branch: main Julia branch: master Old commit: d7496d2 New commit: f6035eb Julia version: 1.12.0-DEV StyledStrings version: 1.11.0(Does not match) Bump invoked by: @LilithHafner Powered by: [BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl) Diff: https://github.com/JuliaLang/StyledStrings.jl/compare/d7496d24d3f05536bce6a7eb4cd8ca05a75c02aa...f6035eb97b516862b16e36cab2ecc6ea8adc3d7c ``` $ git log --oneline d7496d2..f6035eb f6035eb Replace accidental Int64s with Ints 4fcd8bb Use const fields in parser State instead of refs 35a3cdf Load user-customisations lazily 9802b6c Load ScopedValues symbols from their source 9b9cf71 Use branches when choosing how to merge face attrs eada2dc Avoid needlessly creating a new Face in get calls c647af9 Avoid boxing mergedface by making it toplevel a117008 Avoid creating strings for ansi_4bit_color_code 6863348 Improve type inference of face merging f588218 Quick fix for 4d04102adf0d (Optimised SimpleColor) 4d04102 Optimise creation of a SimpleColor from a UInt32 6d3f44d Actually overload Base's escape_string 58507e5 Fully qualify method overloads, avoid importing fc686f3 Explicitly test eachregion c417262 Refactor eachregion to be O(n log n) not O(n^2) f7af623 Use concrete refs in macro parser state struct 41b2446 Check for underline term capability flag 987f776 Treat printing as more than a nothing-return write 43fb018 Add types to some comprehensions d3aa7e1 Improve inference with a function over a closure 6901610 Mention the importance of semantic names in docs 0be209b Better hint at the package capabilities in readme 37b9e4b Load no faces.toml when the DEPOT_PATH is empty ``` Co-authored-by: Dilum Aluthge --- .../md5 | 1 - .../sha512 | 1 - .../md5 | 1 + .../sha512 | 1 + stdlib/StyledStrings.version | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 deps/checksums/StyledStrings-d7496d24d3f05536bce6a7eb4cd8ca05a75c02aa.tar.gz/md5 delete mode 100644 deps/checksums/StyledStrings-d7496d24d3f05536bce6a7eb4cd8ca05a75c02aa.tar.gz/sha512 create mode 100644 deps/checksums/StyledStrings-f6035eb97b516862b16e36cab2ecc6ea8adc3d7c.tar.gz/md5 create mode 100644 deps/checksums/StyledStrings-f6035eb97b516862b16e36cab2ecc6ea8adc3d7c.tar.gz/sha512 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/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 From ac425a597460e8188918dbe1e98a789d85e3d284 Mon Sep 17 00:00:00 2001 From: "Viral B. Shah" Date: Mon, 12 Aug 2024 15:01:03 -0400 Subject: [PATCH 109/115] Bump SparseArrays for SuiteSparse 7.8.0 (#55472) --- .../md5 | 1 + .../sha512 | 1 + .../md5 | 1 - .../sha512 | 1 - .../md5 | 1 + .../sha512 | 1 + deps/checksums/suitesparse | 70 +++++++++---------- deps/libsuitesparse.version | 4 +- stdlib/SparseArrays.version | 2 +- stdlib/SuiteSparse_jll/Project.toml | 4 +- 10 files changed, 43 insertions(+), 43 deletions(-) create mode 100644 deps/checksums/SparseArrays-0dd8d45d55b305458d0d3d3451057589b684f72f.tar.gz/md5 create mode 100644 deps/checksums/SparseArrays-0dd8d45d55b305458d0d3d3451057589b684f72f.tar.gz/sha512 delete mode 100644 deps/checksums/SparseArrays-55976a6e4f883a32e3d3658af50c49879b98fce0.tar.gz/md5 delete mode 100644 deps/checksums/SparseArrays-55976a6e4f883a32e3d3658af50c49879b98fce0.tar.gz/sha512 create mode 100644 deps/checksums/SuiteSparse-e8285dd13a6d5b5cf52d8124793fc4d622d07554.tar.gz/md5 create mode 100644 deps/checksums/SuiteSparse-e8285dd13a6d5b5cf52d8124793fc4d622d07554.tar.gz/sha512 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-55976a6e4f883a32e3d3658af50c49879b98fce0.tar.gz/md5 b/deps/checksums/SparseArrays-55976a6e4f883a32e3d3658af50c49879b98fce0.tar.gz/md5 deleted file mode 100644 index 401900c9f2739..0000000000000 --- a/deps/checksums/SparseArrays-55976a6e4f883a32e3d3658af50c49879b98fce0.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -7b16893f5a49cee4a4d9219afbb57577 diff --git a/deps/checksums/SparseArrays-55976a6e4f883a32e3d3658af50c49879b98fce0.tar.gz/sha512 b/deps/checksums/SparseArrays-55976a6e4f883a32e3d3658af50c49879b98fce0.tar.gz/sha512 deleted file mode 100644 index e8f1bc3c4aaaf..0000000000000 --- a/deps/checksums/SparseArrays-55976a6e4f883a32e3d3658af50c49879b98fce0.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -398028ee8f23ee0b4a5144f5dd03d756cd7575a0b806f351d76339e9521830f75c0c96806a3ee5cebe04853feab51c75c7bcdaaa623acc649bc1a24395df5581 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/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/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/stdlib/SparseArrays.version b/stdlib/SparseArrays.version index 2dc7bd8f5b3b9..019306a3e9f65 100644 --- a/stdlib/SparseArrays.version +++ b/stdlib/SparseArrays.version @@ -1,4 +1,4 @@ SPARSEARRAYS_BRANCH = main -SPARSEARRAYS_SHA1 = 55976a6e4f883a32e3d3658af50c49879b98fce0 +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/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" From 96fd25a764c316e9e09dfd7de8e84d854a73b2cd Mon Sep 17 00:00:00 2001 From: DilumAluthgeBot <43731525+DilumAluthgeBot@users.noreply.github.com> Date: Mon, 12 Aug 2024 23:07:40 -0400 Subject: [PATCH 110/115] =?UTF-8?q?=F0=9F=A4=96=20[master]=20Bump=20the=20?= =?UTF-8?q?JuliaSyntaxHighlighting=20stdlib=20from=2004b2323=20to=20b89dd9?= =?UTF-8?q?9=20(#55474)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stdlib: JuliaSyntaxHighlighting URL: https://github.com/julialang/JuliaSyntaxHighlighting.jl.git Stdlib branch: main Julia branch: master Old commit: 04b2323 New commit: b89dd99 Julia version: 1.12.0-DEV JuliaSyntaxHighlighting version: 1.12.0 Bump invoked by: @tecosaur Powered by: [BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl) Diff: https://github.com/julialang/JuliaSyntaxHighlighting.jl/compare/04b2323c41f6422464c838fe9045700e9ee75e95...b89dd99db56700c47434df6106b6c6afd1c9ed01 ``` $ git log --oneline 04b2323..b89dd99 b89dd99 Actually use the syntax_errors argument fee6aa5 Use a mutable type instead of ref fields ``` Co-authored-by: Dilum Aluthge --- .../md5 | 1 - .../sha512 | 1 - .../md5 | 1 + .../sha512 | 1 + stdlib/JuliaSyntaxHighlighting.version | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 deps/checksums/JuliaSyntaxHighlighting-04b2323c41f6422464c838fe9045700e9ee75e95.tar.gz/md5 delete mode 100644 deps/checksums/JuliaSyntaxHighlighting-04b2323c41f6422464c838fe9045700e9ee75e95.tar.gz/sha512 create mode 100644 deps/checksums/JuliaSyntaxHighlighting-b89dd99db56700c47434df6106b6c6afd1c9ed01.tar.gz/md5 create mode 100644 deps/checksums/JuliaSyntaxHighlighting-b89dd99db56700c47434df6106b6c6afd1c9ed01.tar.gz/sha512 diff --git a/deps/checksums/JuliaSyntaxHighlighting-04b2323c41f6422464c838fe9045700e9ee75e95.tar.gz/md5 b/deps/checksums/JuliaSyntaxHighlighting-04b2323c41f6422464c838fe9045700e9ee75e95.tar.gz/md5 deleted file mode 100644 index 518e2705544ed..0000000000000 --- a/deps/checksums/JuliaSyntaxHighlighting-04b2323c41f6422464c838fe9045700e9ee75e95.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -956fe26df1daca727ec15bfbc175584f diff --git a/deps/checksums/JuliaSyntaxHighlighting-04b2323c41f6422464c838fe9045700e9ee75e95.tar.gz/sha512 b/deps/checksums/JuliaSyntaxHighlighting-04b2323c41f6422464c838fe9045700e9ee75e95.tar.gz/sha512 deleted file mode 100644 index 786dd666f2927..0000000000000 --- a/deps/checksums/JuliaSyntaxHighlighting-04b2323c41f6422464c838fe9045700e9ee75e95.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -20c7990134634dd252909dfa2c43f7b77d427a77f1b726eefdc47781fc3ad46152e81e612d4091541ffb32323154cb5a696157cd24d7a71087d5883720e03728 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/stdlib/JuliaSyntaxHighlighting.version b/stdlib/JuliaSyntaxHighlighting.version index b076cfa26b5aa..280db66afe5f9 100644 --- a/stdlib/JuliaSyntaxHighlighting.version +++ b/stdlib/JuliaSyntaxHighlighting.version @@ -1,4 +1,4 @@ JULIASYNTAXHIGHLIGHTING_BRANCH = main -JULIASYNTAXHIGHLIGHTING_SHA1 = 04b2323c41f6422464c838fe9045700e9ee75e95 +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 From 5eda5972269558cb811ec695e399eb14579535c8 Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Tue, 13 Aug 2024 16:44:41 +0200 Subject: [PATCH 111/115] make the previous active module in the REPL a non-global (#55418) The intent of the active module seems to have been for it to be REPL specific but this global kind of breaks that. Co-authored-by: KristofferC --- stdlib/REPL/src/LineEdit.jl | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) 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) From 881be64de02e690f0753fb404647d216d839153d Mon Sep 17 00:00:00 2001 From: matthias314 <56549971+matthias314@users.noreply.github.com> Date: Tue, 13 Aug 2024 10:45:19 -0400 Subject: [PATCH 112/115] fix hierarchy level of "API reference" in `Dates` documentation (#55483) Currently, "API reference" is at the same level as "Dates" although it is a subsection of it. This looks particularly weird in the PDF version of the manual: Section 67 is "Dates" and Section 68 is "API reference". Note that I didn't change the nesting level of the subsection "Constants" at the end of the file. As a result, it is now at the same level as "Dates and Time Types" and "Dates Functions". Before it was a subsection of the latter, which appears wrong to me. --- stdlib/Dates/docs/src/index.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) 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 From b7aa5e37402e2a0c81f9f2b80e89cf0f85ff6da6 Mon Sep 17 00:00:00 2001 From: Oscar Smith Date: Tue, 13 Aug 2024 11:46:04 -0400 Subject: [PATCH 113/115] simplify complex atanh and remove singularity perturbation (#55268) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fixes https://github.com/JuliaLang/julia/issues/55266, and use `inv(z)` rather than `1/z` and use `muladd` in a couple places. --------- Co-authored-by: Mosè Giordano --- base/complex.jl | 17 +++++++---------- test/complex.jl | 6 ++++++ 2 files changed, 13 insertions(+), 10 deletions(-) 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/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 From 2a4e2b1d95c15654eea7965f123f72890b84e594 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Wed, 14 Aug 2024 11:34:06 -0400 Subject: [PATCH 114/115] fix Event to use normal Condition variable (#55441) ThreadSynchronizer is only for things that are very trivial, as there are a lot of things they are forbidden from doing (such as waiting for a Task to set it). Happened to notice while reviewing https://github.com/JuliaLang/julia/pull/55439#pullrequestreview-2231026949 that this was still using the pre-v1.2 style lock, which makes this mostly useless in v1.4+ --- base/lock.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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) From c7309d05c16ba9a42a60eee3a03650d3d42a158b Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Wed, 14 Aug 2024 17:05:05 -0400 Subject: [PATCH 115/115] subtyping: fast path for lhs union and rhs typevar (#55413) Fixes #55230 --- src/subtype.c | 16 +++++++++++- test/subtype.jl | 67 +++++++++++++++++++++++++++++++++++++------------ 2 files changed, 66 insertions(+), 17 deletions(-) diff --git a/src/subtype.c b/src/subtype.c index 6f6520c5df980..4118bbeab649b 100644 --- a/src/subtype.c +++ b/src/subtype.c @@ -1312,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)) { diff --git a/test/subtype.jl b/test/subtype.jl index af023ef8ca72f..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 @@ -2686,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