From 2b217590ab056714efe25d97bd992e2bb789180b Mon Sep 17 00:00:00 2001 From: Milan Bouchet-Valat Date: Tue, 6 Jul 2021 20:13:14 +0200 Subject: [PATCH 01/74] Fix pivoted cholesky docstrings (#41298) (cherry picked from commit 7409a1c007b7773544223f0e0a2d8aaee4a45172) --- stdlib/LinearAlgebra/src/cholesky.jl | 68 +++++++++++++++------------- 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/stdlib/LinearAlgebra/src/cholesky.jl b/stdlib/LinearAlgebra/src/cholesky.jl index 6e381243faf43..0030ba360602c 100644 --- a/stdlib/LinearAlgebra/src/cholesky.jl +++ b/stdlib/LinearAlgebra/src/cholesky.jl @@ -110,8 +110,10 @@ positive semi-definite matrix `A`. This is the return type of [`cholesky(_, Val( the corresponding matrix factorization function. The triangular Cholesky factor can be obtained from the factorization `F::CholeskyPivoted` -via `F.L` and `F.U`, and the permutation via `F.p`, where `A[F.p, F.p] ≈ F.U' * F.U ≈ F.L * F.L'`, -or alternatively `A ≈ F.U[:, F.p]' * F.U[:, F.p] ≈ F.L[F.p, :] * F.L[F.p, :]'`. +via `F.L` and `F.U`, and the permutation via `F.p`, where `A[F.p, F.p] ≈ Ur' * Ur ≈ Lr * Lr'` +with `Ur = F.U[1:F.rank, :]` and `Lr = F.L[:, 1:F.rank]`, or alternatively +`A ≈ Up' * Up ≈ Lp * Lp'` with `Up = F.U[1:F.rank, invperm(F.p)]` and +`Lp = F.L[invperm(F.p), 1:F.rank]`. The following functions are available for `CholeskyPivoted` objects: [`size`](@ref), [`\\`](@ref), [`inv`](@ref), [`det`](@ref), and [`rank`](@ref). @@ -120,25 +122,28 @@ Iterating the decomposition produces the components `L` and `U`. # Examples ```jldoctest -julia> A = [4. 12. -16.; 12. 37. -43.; -16. -43. 98.] -3×3 Matrix{Float64}: - 4.0 12.0 -16.0 - 12.0 37.0 -43.0 - -16.0 -43.0 98.0 +julia> X = [1.0, 2.0, 3.0, 4.0]; -julia> C = cholesky(A, Val(true)) +julia> A = X * X'; + +julia> C = cholesky(A, Val(true), check = false) CholeskyPivoted{Float64, Matrix{Float64}} -U factor with rank 3: -3×3 UpperTriangular{Float64, Matrix{Float64}}: - 9.89949 -4.34366 -1.61624 - â‹… 4.25825 1.1694 - â‹… â‹… 0.142334 +U factor with rank 1: +4×4 UpperTriangular{Float64, Matrix{Float64}}: + 4.0 2.0 3.0 1.0 + â‹… 0.0 6.0 2.0 + â‹… â‹… 9.0 3.0 + â‹… â‹… â‹… 1.0 permutation: -3-element Vector{Int64}: - 3 +4-element Vector{Int64}: + 4 2 + 3 1 +julia> C.U[1:C.rank, :]' * C.U[1:C.rank, :] ≈ A[C.p, C.p] +true + julia> l, u = C; # destructuring via iteration julia> l == C.L && u == C.U @@ -398,8 +403,9 @@ and return a [`CholeskyPivoted`](@ref) factorization. The matrix `A` can either or [`Hermitian`](@ref) [`StridedMatrix`](@ref) or a *perfectly* symmetric or Hermitian `StridedMatrix`. The triangular Cholesky factor can be obtained from the factorization `F` via `F.L` and `F.U`, -and the permutation via `F.p`, where `A[F.p, F.p] ≈ F.U' * F.U ≈ F.L * F.L'`, or alternatively -`A ≈ F.U[:, F.p]' * F.U[:, F.p] ≈ F.L[F.p, :] * F.L[F.p, :]'`. +and the permutation via `F.p`, where `A[F.p, F.p] ≈ Ur' * Ur ≈ Lr * Lr'` with `Ur = F.U[1:F.rank, :]` +and `Lr = F.L[:, 1:F.rank]`, or alternatively `A ≈ Up' * Up ≈ Lp * Lp'` with +`Up = F.U[1:F.rank, invperm(F.p)]` and `Lp = F.L[invperm(F.p), 1:F.rank]`. The following functions are available for `CholeskyPivoted` objects: [`size`](@ref), [`\\`](@ref), [`inv`](@ref), [`det`](@ref), and [`rank`](@ref). @@ -416,26 +422,26 @@ validity (via [`issuccess`](@ref)) lies with the user. # Examples ```jldoctest -julia> A = [4. 12. -16.; 12. 37. -43.; -16. -43. 98.] -3×3 Matrix{Float64}: - 4.0 12.0 -16.0 - 12.0 37.0 -43.0 - -16.0 -43.0 98.0 +julia> X = [1.0, 2.0, 3.0, 4.0]; + +julia> A = X * X'; -julia> C = cholesky(A, Val(true)) +julia> C = cholesky(A, Val(true), check = false) CholeskyPivoted{Float64, Matrix{Float64}} -U factor with rank 3: -3×3 UpperTriangular{Float64, Matrix{Float64}}: - 9.89949 -4.34366 -1.61624 - â‹… 4.25825 1.1694 - â‹… â‹… 0.142334 +U factor with rank 1: +4×4 UpperTriangular{Float64, Matrix{Float64}}: + 4.0 2.0 3.0 1.0 + â‹… 0.0 6.0 2.0 + â‹… â‹… 9.0 3.0 + â‹… â‹… â‹… 1.0 permutation: -3-element Vector{Int64}: - 3 +4-element Vector{Int64}: + 4 2 + 3 1 -julia> C.U[:, C.p]' * C.U[:, C.p] ≈ A +julia> C.U[1:C.rank, :]' * C.U[1:C.rank, :] ≈ A[C.p, C.p] true julia> l, u = C; # destructuring via iteration From 35c5fc16250dad33387984a4583aa31bbf48b586 Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Tue, 6 Jul 2021 17:41:21 -0400 Subject: [PATCH 02/74] fix #41157, unnecessary assertion on `Tuple{Union{}}` (#41483) (cherry picked from commit 4733c0038fc072f150f5ec649643301dd4f215e7) --- src/intrinsics.cpp | 1 - test/compiler/codegen.jl | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/intrinsics.cpp b/src/intrinsics.cpp index 7d0e94fd30783..e37ee264398e9 100644 --- a/src/intrinsics.cpp +++ b/src/intrinsics.cpp @@ -284,7 +284,6 @@ static Value *emit_unboxed_coercion(jl_codectx_t &ctx, Type *to, Value *unboxed) Type *ty = unboxed->getType(); if (ty == to) return unboxed; - assert(to->isIntOrPtrTy() || to->isFloatingPointTy()); bool frompointer = ty->isPointerTy(); bool topointer = to->isPointerTy(); const DataLayout &DL = jl_data_layout; diff --git a/test/compiler/codegen.jl b/test/compiler/codegen.jl index df29a339d5a85..f232b246a9fc9 100644 --- a/test/compiler/codegen.jl +++ b/test/compiler/codegen.jl @@ -593,3 +593,7 @@ f41438(y) = y[].x @test B41438.body.layout === C_NULL @test f41438(Ref{A41438}(A41438(C_NULL))) === C_NULL @test f41438(Ref{B41438}(B41438(C_NULL))) === C_NULL + +# issue #41157 +f41157(a, b) = a[1] = b[1] +@test_throws BoundsError f41157(Tuple{Int}[], Tuple{Union{}}[]) From 26bfefa69047fdef26334f3a8d0c40329e979233 Mon Sep 17 00:00:00 2001 From: Simeon Schaub Date: Fri, 2 Jul 2021 01:59:25 +0200 Subject: [PATCH 03/74] fix `partially_inline!` with `isdefined` (#40628) ref https://github.com/JuliaLang/julia/pull/40562#issuecomment-824912109 (cherry picked from commit 10b010f6011996558c56a5c46d97e9a201286ea0) --- base/meta.jl | 29 ++++++++++++++++++++++++++++- test/meta.jl | 30 ++++++++++++++++++++++++++---- 2 files changed, 54 insertions(+), 5 deletions(-) diff --git a/base/meta.jl b/base/meta.jl index aaf29b551cd0d..b483630a92f8f 100644 --- a/base/meta.jl +++ b/base/meta.jl @@ -370,7 +370,10 @@ function _partially_inline!(@nospecialize(x), slot_replacements::Vector{Any}, if isa(x, Expr) head = x.head if head === :static_parameter - return QuoteNode(static_param_values[x.args[1]]) + if isassigned(static_param_values, x.args[1]) + return QuoteNode(static_param_values[x.args[1]]) + end + return x elseif head === :cfunction @assert !isa(type_signature, UnionAll) || !isempty(spvals) if !isa(x.args[2], QuoteNode) # very common no-op @@ -413,6 +416,30 @@ function _partially_inline!(@nospecialize(x), slot_replacements::Vector{Any}, x.args[2] += statement_offset elseif head === :enter x.args[1] += statement_offset + elseif head === :isdefined + arg = x.args[1] + # inlining a QuoteNode or literal into `Expr(:isdefined, x)` is invalid, replace with true + if isa(arg, Core.SlotNumber) + id = arg.id + if 1 <= id <= length(slot_replacements) + replacement = slot_replacements[id] + if isa(replacement, Union{Core.SlotNumber, GlobalRef, Symbol}) + return Expr(:isdefined, replacement) + else + @assert !isa(replacement, Expr) + return true + end + end + return Expr(:isdefined, Core.SlotNumber(id + slot_offset)) + elseif isexpr(arg, :static_parameter) + if isassigned(static_param_values, arg.args[1]) + return true + end + return x + else + @assert isa(arg, Union{GlobalRef, Symbol}) + return x + end elseif !is_meta_expr_head(head) partially_inline!(x.args, slot_replacements, type_signature, static_param_values, slot_offset, statement_offset, boundscheck) diff --git a/test/meta.jl b/test/meta.jl index ab073668677c6..5bdb988f41b6d 100644 --- a/test/meta.jl +++ b/test/meta.jl @@ -241,7 +241,29 @@ ci = code_lowered(f, Tuple{Int})[1] g(::Val{x}) where {x} = x ? 1 : 0 ci = code_lowered(g, Tuple{Val{true}})[1] -@test Meta.partially_inline!(ci.code, [], Tuple{typeof(g),Val{true}}, Any[Val{true}], 0, 0, :propagate)[1] == - Core.GotoIfNot(QuoteNode(Val{true}), 3) -@test Meta.partially_inline!(ci.code, [], Tuple{typeof(g),Val{true}}, Any[Val{true}], 0, 2, :propagate)[1] == - Core.GotoIfNot(QuoteNode(Val{true}), 5) +@test Meta.partially_inline!(ci.code, [], Tuple{typeof(g),Val{true}}, Any[true], 0, 0, :propagate)[1] == + Core.GotoIfNot(QuoteNode(true), 3) +@test Meta.partially_inline!(ci.code, [], Tuple{typeof(g),Val{true}}, Any[true], 0, 2, :propagate)[1] == + Core.GotoIfNot(QuoteNode(true), 5) + +@testset "inlining with isdefined" begin + isdefined_slot(x) = @isdefined(x) + ci = code_lowered(isdefined_slot, Tuple{Int})[1] + @test Meta.partially_inline!(copy(ci.code), [], Tuple{typeof(isdefined_slot), Int}, + [], 0, 0, :propagate)[1] == Expr(:isdefined, Core.SlotNumber(2)) + @test Meta.partially_inline!(copy(ci.code), [isdefined_slot, 1], Tuple{typeof(isdefined_slot), Int}, + [], 0, 0, :propagate)[1] == true + + isdefined_sparam(::T) where {T} = @isdefined(T) + ci = code_lowered(isdefined_sparam, Tuple{Int})[1] + @test Meta.partially_inline!(copy(ci.code), [], Tuple{typeof(isdefined_sparam), Int}, + Any[Int], 0, 0, :propagate)[1] == true + @test Meta.partially_inline!(copy(ci.code), [], Tuple{typeof(isdefined_sparam), Int}, + [], 0, 0, :propagate)[1] == Expr(:isdefined, Expr(:static_parameter, 1)) + + @eval isdefined_globalref(x) = $(Expr(:isdefined, GlobalRef(Base, :foo))) + ci = code_lowered(isdefined_globalref, Tuple{Int})[1] + @test Meta.partially_inline!(copy(ci.code), Any[isdefined_globalref, 1], Tuple{typeof(isdefined_globalref), Int}, + [], 0, 0, :propagate)[1] == Expr(:isdefined, GlobalRef(Base, :foo)) + +end From 8ebbd94a83fcd4708bff898767686f27fdcc203a Mon Sep 17 00:00:00 2001 From: Simeon Schaub Date: Fri, 2 Jul 2021 02:01:58 +0200 Subject: [PATCH 04/74] fix slurping into function definition (#40738) Discovered while working on #40737. Currently, this throws an unintuitive error: ```julia julia> a, f()... = 1, 2, 3 ERROR: syntax: ssavalue with no def Stacktrace: [1] top-level scope @ REPL[1]:1 ``` Might as well fix this properly - Why not allow function definitions to slurp a little from time to time? ;) (cherry picked from commit 5c49a0d4890e4cd63931718797adbb8143155e75) --- src/julia-syntax.scm | 12 ++++++++---- test/syntax.jl | 12 ++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index 420eeaf51f747..f00ea0c9ba6d9 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -1456,7 +1456,7 @@ (cons R elts))) ((vararg? L) (if (null? (cdr lhss)) - (let ((temp (make-ssavalue))) + (let ((temp (if (eventually-call? (cadr L)) (gensy) (make-ssavalue)))) `(block ,@(reverse stmts) (= ,temp (tuple ,@rhss)) ,@(reverse after) @@ -2155,9 +2155,13 @@ ((eq? l x) #t) (else (in-lhs? x (cdr lhss))))))) ;; in-lhs? also checks for invalid syntax, so always call it first - (let* ((xx (if (or (and (not (in-lhs? x lhss)) (symbol? x)) - (ssavalue? x)) - x (make-ssavalue))) + (let* ((xx (cond ((or (and (not (in-lhs? x lhss)) (symbol? x)) + (ssavalue? x)) + x) + ((and (pair? lhss) (vararg? (last lhss)) + (eventually-call? (cadr (last lhss)))) + (gensy)) + (else (make-ssavalue)))) (ini (if (eq? x xx) '() (list (sink-assignment xx (expand-forms x))))) (n (length lhss)) ;; skip last assignment if it is an all-underscore vararg diff --git a/test/syntax.jl b/test/syntax.jl index 707437096ef14..19f692baec95c 100644 --- a/test/syntax.jl +++ b/test/syntax.jl @@ -2937,3 +2937,15 @@ end @test eval(Meta.parse("`a\\\r\nb`")) == `ab` @test eval(Meta.parse("`a\\\rb`")) == `ab` end + +@testset "slurping into function def" begin + x, f()... = [1, 2, 3] + @test x == 1 + @test f() == [2, 3] + # test that call to `Base.rest` is outside the definition of `f` + @test f() === f() + + x, f()... = 1, 2, 3 + @test x == 1 + @test f() == (2, 3) +end From b1fd8f0db63038da61db1f539649bf995a838a44 Mon Sep 17 00:00:00 2001 From: Dilum Aluthge Date: Sun, 20 Jun 2021 03:09:58 -0400 Subject: [PATCH 05/74] Transition the `coverage-linux64` pipeline to Buildkite (#41238) * Transition the `coverage-linux64` pipeline to Buildkite * Simplify, run inside of a sandbox * Upload coverage reports to Codecov and Coveralls * Add `COVERALLS_TOKEN` Co-authored-by: Elliot Saba (cherry picked from commit 9d5f31e9231c1d77e24ee820908e32f559e23057) --- .buildkite/coverage-linux64/0_webui.yml | 16 +++ .buildkite/coverage-linux64/README.md | 6 + .buildkite/coverage-linux64/pipeline.yml | 44 +++++++ .buildkite/coverage-linux64/run_tests_base.jl | 36 ++++++ .../coverage-linux64/upload_coverage.jl | 115 ++++++++++++++++++ 5 files changed, 217 insertions(+) create mode 100644 .buildkite/coverage-linux64/0_webui.yml create mode 100644 .buildkite/coverage-linux64/README.md create mode 100644 .buildkite/coverage-linux64/pipeline.yml create mode 100644 .buildkite/coverage-linux64/run_tests_base.jl create mode 100644 .buildkite/coverage-linux64/upload_coverage.jl diff --git a/.buildkite/coverage-linux64/0_webui.yml b/.buildkite/coverage-linux64/0_webui.yml new file mode 100644 index 0000000000000..6dafcd86f6bcd --- /dev/null +++ b/.buildkite/coverage-linux64/0_webui.yml @@ -0,0 +1,16 @@ +# This file represents what is put into the webUI. +# It is purely for keeping track of the changes we make to the webUI configuration; modifying this file has no effect. +# We use the `cryptic` buildkite plugin to provide secrets management, which requires some integration into the WebUI's steps. +agents: + queue: "julia" + sandbox.jl: "true" + +steps: + - label: ":unlock: Unlock secrets, launch pipelines" + plugins: + - staticfloat/cryptic: + # Our signed pipelines must have a `signature` or `signature_file` parameter that + # verifies the treehash of the pipeline itself and the inputs listed in `inputs` + signed_pipelines: + - pipeline: .buildkite/coverage-linux64/pipeline.yml + signature: "U2FsdGVkX18eQWpd3hMYLO5Kd+6K+oBoLk1I6J3qIw7lc6g5/jaeWyq/wralosZCfTzyjS4NstNKFvhQf3KDPEBVElipNvTxoWOjVLRVOrfBqqvTkQN4xVosY/r026Gy" diff --git a/.buildkite/coverage-linux64/README.md b/.buildkite/coverage-linux64/README.md new file mode 100644 index 0000000000000..8cfb31d698225 --- /dev/null +++ b/.buildkite/coverage-linux64/README.md @@ -0,0 +1,6 @@ +# Coverage pipeline + +We run coverage on a separate pipeline, that uses a scheduled build rather than webhooks. +The pipeline is here: https://buildkite.com/julialang/julia-coverage-linux64 + +It contains [its own webui steps](0_webuiy.ml) (listed here in this repository for clarity) and its own [pipeline.yml](pipeline.yml). diff --git a/.buildkite/coverage-linux64/pipeline.yml b/.buildkite/coverage-linux64/pipeline.yml new file mode 100644 index 0000000000000..078b00254c4f9 --- /dev/null +++ b/.buildkite/coverage-linux64/pipeline.yml @@ -0,0 +1,44 @@ +# These steps should only run on `sandbox.jl` machines, not `docker`-isolated ones +# since we need nestable sandboxing. The rootfs images being used here are built from +# the `.buildkite/rootfs_images/llvm-passes.jl` file. +agents: + queue: "julia" + # Only run on `sandbox.jl` machines (not `docker`-isolated ones) since we need nestable sandboxing + sandbox.jl: "true" + os: "linux" + +steps: + - label: ":unlock: :coverage: Run coverage test" + plugins: + - staticfloat/cryptic: + variables: + - CODECOV_TOKEN="U2FsdGVkX19l0fhdBabbuiEdysyEabkJLRHfxm7CNRkuGbnwPV365sxxC7Czs/CVcws0N1oB4pVwALRRMe36oA==" + - COVERALLS_TOKEN="U2FsdGVkX19zopI0hMNzzi2UUOvNVFD8Y0iisFnO/ryVxU7Tit8ZEaeN+gxodRx4CosUUh192F1+q3dTMWRIvw==" + - JuliaCI/julia#v1: + version: 1.6 + - staticfloat/sandbox#v1: + rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v1/llvm-passes.tar.gz + rootfs_treehash: "f3ed53f159e8f13edfba8b20ebdb8ece73c1b8a8" + uid: 1000 + gid: 1000 + commands: | + echo "--- Build Julia from source" + make -j 6 + + echo "--- Print Julia version info" + ./julia -e 'using InteractiveUtils; InteractiveUtils.versioninfo()' + ./julia -e '@info "" Sys.CPU_THREADS' + # this is necessary to make sure that the LibGit2 tests passes + git config --global init.defaultBranch master + + echo "--- Run Julia tests with code coverage enabled" + # Run the actual tests + ./julia --code-coverage=all --sysimage-native-code=no .buildkite/coverage-linux64/run_tests_base.jl + + echo "--- Process and upload coverage information" + ./julia .buildkite/coverage-linux64/upload_coverage.jl + timeout_in_minutes: 600 # 600 minutes = 10 hours + +# We must accept the signed job id secret in order to propagate secrets +env: + BUILDKITE_PLUGIN_CRYPTIC_BASE64_SIGNED_JOB_ID_SECRET: ${BUILDKITE_PLUGIN_CRYPTIC_BASE64_SIGNED_JOB_ID_SECRET?} diff --git a/.buildkite/coverage-linux64/run_tests_base.jl b/.buildkite/coverage-linux64/run_tests_base.jl new file mode 100644 index 0000000000000..5386828aa4e14 --- /dev/null +++ b/.buildkite/coverage-linux64/run_tests_base.jl @@ -0,0 +1,36 @@ +# When running this file, make sure to set the `--code-coverage=all` command-line flag. + +# Important note: even if one or more tests fail, we will still exit with status code 0. + +# The reason for this is that we always want to upload code coverage, even if some of the +# tests fail. Therefore, even if the `coverage-linux64` pipeline passes, you should not +# assume that all of the tests passed. If you want to know if all of the tests are passing, +# please look at the status of the `tester_linux64` pipeline. + +const include_tests = String[] + +const exclude_tests = String[] + +empty!(Base.DEPOT_PATH) +push!(Base.DEPOT_PATH, mktempdir(; cleanup = true)) + +module ChooseTests + include(joinpath(dirname(dirname(@__DIR__)), "test", "choosetests.jl")) +end + +const tests = ChooseTests.choosetests() |> + first |> + x -> setdiff(x, exclude_tests) |> + x -> vcat(x, include_tests) |> + unique |> + sort + +const ncores = min(Sys.CPU_THREADS, Threads.nthreads()) + +@info "" ncores Sys.CPU_THREADS Threads.nthreads() + +try + Base.runtests(tests; ncores) +catch ex + @error "" exception=(ex, catch_backtrace()) +end diff --git a/.buildkite/coverage-linux64/upload_coverage.jl b/.buildkite/coverage-linux64/upload_coverage.jl new file mode 100644 index 0000000000000..04ddd9651861e --- /dev/null +++ b/.buildkite/coverage-linux64/upload_coverage.jl @@ -0,0 +1,115 @@ +empty!(Base.DEPOT_PATH) +push!(Base.DEPOT_PATH, mktempdir(; cleanup = true)) + +import Pkg +import Logging +import TOML + +Pkg.add(; name = "Coverage", uuid = "a2441757-f6aa-5fb2-8edb-039e3f45d037", version = "1") +Pkg.precompile() + +import Coverage + +function get_external_stdlib_names(stdlib_dir::AbstractString) + filename_list = filter(x -> isfile(joinpath(stdlib_dir, x)), readdir(stdlib_dir)) + # find all of the files like `Pkg.version`, `Statistics.version`, etc. + regex_matches_or_nothing = match.(Ref(r"^([\w].*?)\.version$"), filename_list) + regex_matches = filter(x -> x !== nothing, regex_matches_or_nothing) + # get the names of the external stdlibs, like `Pkg`, `Statistics`, etc. + external_stdlib_names = only.(regex_matches) + unique!(external_stdlib_names) + sort!(external_stdlib_names) + @info "# Begin list of external stdlibs" + for (i, x) in enumerate(external_stdlib_names) + @info "$(i). $(x)" + end + @info "# End list of external stdlibs" + return external_stdlib_names +end + +function get_external_stdlib_prefixes(stdlib_dir::AbstractString) + external_stdlib_names = get_external_stdlib_names(stdlib_dir) + prefixes_1 = joinpath.(Ref(stdlib_dir), external_stdlib_names, Ref("")) + prefixes_2 = joinpath.(Ref(stdlib_dir), string.(external_stdlib_names, Ref("-"))) + prefixes = vcat(prefixes_1, prefixes_2) + unique!(prefixes) + sort!(prefixes) + # example of what `prefixes` might look like: + # 4-element Vector{String}: + # "stdlib/Pkg-" + # "stdlib/Pkg/" + # "stdlib/Statistics-" + # "stdlib/Statistics/" + return prefixes +end + +function print_coverage_summary(fc::Coverage.FileCoverage) + cov_lines, tot_lines = Coverage.get_summary(fc) + if cov_lines == tot_lines == 0 + cov_pct = 0 + else + cov_pct = floor(Int, cov_lines/tot_lines * 100) + end + pad_1 = 71 + pad_2 = 15 + pad_3 = 15 + col_1 = rpad(fc.filename, pad_1) + col_2 = rpad(string(cov_pct, " %"), pad_2) + col_3 = string( + rpad(string(cov_lines), pad_3), + string(tot_lines), + ) + @info "$(col_1) $(col_2) $(col_3)" + return nothing +end + +function print_coverage_summary( + fcs::Vector{Coverage.FileCoverage}, description::AbstractString, + ) + cov_lines, tot_lines = Coverage.get_summary(fcs) + if cov_lines == tot_lines == 0 + cov_pct = 0 + else + cov_pct = floor(Int, cov_lines/tot_lines * 100) + end + @info "$(description): $(cov_pct)% ($(cov_lines)/$(tot_lines))" + return nothing +end + +# `Coverage.process_folder` will have a LOT of `@info` statements that will make the log +# way too long. So before we run `Coverage.process_folder`, we disable logging for `@info` +# statements. After we run `Coverage.process_folder`, we re-enable logging for `@info` +# statements. +Logging.disable_logging(Logging.Info) +const fcs = Coverage.merge_coverage_counts( + Coverage.process_folder("base"), + Coverage.process_folder("stdlib"), +); +Logging.disable_logging(Logging.Debug) + +# Only include source code files. Exclude test files, benchmarking files, etc. +filter!(fcs) do fc + occursin(r"^base\/", fc.filename) || occursin("/src/", fc.filename) +end; + +# Exclude all external stdlibs (stdlibs that live in external repos). +const external_stdlib_prefixes = get_external_stdlib_prefixes("stdlib") +filter!(fcs) do fc + all(x -> !startswith(fc.filename, x), external_stdlib_prefixes) +end; + +# Exclude all stdlib JLLs (stdlibs of the form `stdlib/*_jll/`). +filter!(fcs) do fc + !occursin(r"^stdlib\/[A-Za-z0-9]*?_jll\/", fc.filename) +end + +sort!(fcs; by = fc -> fc.filename) + +print_coverage_summary.(fcs); +print_coverage_summary(fcs, "Total") + +# In order to upload to Codecov, you need to have the `CODECOV_TOKEN` environment variable defined. +Coverage.Codecov.submit_local(fcs) + +# In order to upload to Coveralls, you need to have the `COVERALLS_TOKEN` environment variable defined. +Coverage.Coveralls.submit_local(fcs) From cea02c0d21f387012775835aeecf935b905258ba Mon Sep 17 00:00:00 2001 From: Dilum Aluthge Date: Sat, 26 Jun 2021 11:25:24 -0400 Subject: [PATCH 06/74] Code coverage: fix the code coverage pipeline (#41375) * Code coverage: fix the code coverage pipeline * Run all tests (cherry picked from commit 05e41385de563a2e8aeea9000a7e381fd9bb3318) --- .../coverage-linux64/upload_coverage.jl | 136 +++++++++++++++--- 1 file changed, 120 insertions(+), 16 deletions(-) diff --git a/.buildkite/coverage-linux64/upload_coverage.jl b/.buildkite/coverage-linux64/upload_coverage.jl index 04ddd9651861e..8d14cded56140 100644 --- a/.buildkite/coverage-linux64/upload_coverage.jl +++ b/.buildkite/coverage-linux64/upload_coverage.jl @@ -10,6 +10,24 @@ Pkg.precompile() import Coverage +function process_folders() + # `Coverage.process_folder` will have a LOT of `@info` statements that will make the log + # way too long. So before we run `Coverage.process_folder`, we disable logging for `@info` + # statements. After we run `Coverage.process_folder`, we re-enable logging for `@info` + # statements. + Logging.disable_logging(Logging.Info) + fcs_base = Coverage.process_folder("base"); + fcs_stdlib = Coverage.process_folder("stdlib"); + Logging.disable_logging(Logging.Debug) + + fcs = Coverage.merge_coverage_counts( + fcs_base, + fcs_stdlib, + ); + + return fcs +end + function get_external_stdlib_names(stdlib_dir::AbstractString) filename_list = filter(x -> isfile(joinpath(stdlib_dir, x)), readdir(stdlib_dir)) # find all of the files like `Pkg.version`, `Statistics.version`, etc. @@ -76,16 +94,90 @@ function print_coverage_summary( return nothing end -# `Coverage.process_folder` will have a LOT of `@info` statements that will make the log -# way too long. So before we run `Coverage.process_folder`, we disable logging for `@info` -# statements. After we run `Coverage.process_folder`, we re-enable logging for `@info` -# statements. -Logging.disable_logging(Logging.Info) -const fcs = Coverage.merge_coverage_counts( - Coverage.process_folder("base"), - Coverage.process_folder("stdlib"), -); -Logging.disable_logging(Logging.Debug) +function buildkite_env(name::String) + value = String(strip(ENV[name])) + if isempty(value) + throw(ErrorException("environment variable $(name) is empty")) + end + return value +end + +function buildkite_env(name_1::String, name_2::String, default::String) + value_1 = String(strip(ENV[name_1])) + value_2 = String(strip(ENV[name_2])) + !isempty(value_1) && return value_1 + !isempty(value_2) && return value_2 + return default +end + +function buildkite_branch_and_commit() + branch = buildkite_env("BUILDKITE_BRANCH") + commit = buildkite_env("BUILDKITE_COMMIT") + head_rev_parse = String(strip(read(`git rev-parse HEAD`, String))) + if strip(commit) == "HEAD" + commit = head_rev_parse + end + if commit !== head_rev_parse + msg = "mismatch" + @error msg commit head_rev_parse + throw(ErrorException(msg)) + end + if !occursin(r"^[a-f0-9]{40}$", commit) + msg = "BUILDKITE_COMMIT does not look like a long commit SHA" + @error msg commit + throw(ErrorException(msg)) + end + return (; branch, commit) +end + +function codecov_buildkite_add_local_to_kwargs() + branch, commit = buildkite_branch_and_commit() + kwargs = Coverage.Codecov.set_defaults( + Dict(); + branch, + commit, + ) + return kwargs +end + +function coveralls_buildkite_query_git_info() + branch, commit = buildkite_branch_and_commit() + remote_name = "origin" + remote = buildkite_env("BUILDKITE_REPO") + message = buildkite_env("BUILDKITE_MESSAGE") + author_name = buildkite_env( + "BUILDKITE_BUILD_AUTHOR", + "BUILDKITE_BUILD_CREATOR", + "", + ) + author_email = buildkite_env( + "BUILDKITE_BUILD_AUTHOR_EMAIL", + "BUILDKITE_BUILD_CREATOR_EMAIL", + "", + ) + remotes = [ + Dict( + "name" => remote_name, + "url" => remote, + ) + ] + head = Dict( + "id" => commit, + "author_name" => author_name, + "author_email" => author_email, + "committer_name" => author_name, + "committer_email" => author_email, + "message" => message, + ) + git_info = Dict( + "branch" => branch, + "remotes" => remotes, + "head" => head, + ) + return git_info +end + +const fcs = process_folders() # Only include source code files. Exclude test files, benchmarking files, etc. filter!(fcs) do fc @@ -101,15 +193,27 @@ end; # Exclude all stdlib JLLs (stdlibs of the form `stdlib/*_jll/`). filter!(fcs) do fc !occursin(r"^stdlib\/[A-Za-z0-9]*?_jll\/", fc.filename) -end +end; -sort!(fcs; by = fc -> fc.filename) +sort!(fcs; by = fc -> fc.filename); print_coverage_summary.(fcs); print_coverage_summary(fcs, "Total") -# In order to upload to Codecov, you need to have the `CODECOV_TOKEN` environment variable defined. -Coverage.Codecov.submit_local(fcs) +let + git_info = coveralls_buildkite_query_git_info() + @info "" git_info + @info "" git_info["branch"] + @info "" git_info["head"] -# In order to upload to Coveralls, you need to have the `COVERALLS_TOKEN` environment variable defined. -Coverage.Coveralls.submit_local(fcs) + # In order to upload to Coveralls, you need to have the `COVERALLS_TOKEN` environment variable defined. + Coverage.Coveralls.submit_local(fcs, git_info) +end + +let + kwargs = codecov_buildkite_add_local_to_kwargs() + @info "" kwargs + + # In order to upload to Codecov, you need to have the `CODECOV_TOKEN` environment variable defined. + Coverage.Codecov.submit_generic(fcs, kwargs) +end From 1ca346775577e1a71b603a30211b906c6739f3a7 Mon Sep 17 00:00:00 2001 From: Elliot Saba Date: Tue, 6 Jul 2021 20:24:45 -0700 Subject: [PATCH 07/74] Add embedding and whitespace jobs to buildkite (#41321) * Add "Check whitespace" buildkite job * Add `key` values for later `wait` blocks * Add "embedding tests" to buildkite configuration * Eliminate unnecessary work in buildkite builds Don't bother to precompile the Julia system image like we normally would want to if we're just going to run things once. Also use `JULIA_NUM_CORES` instead of hard-coding `-j 6` into the buildsystem. * Update embedding.yml * Update whitespace.yml (cherry picked from commit a2af84564cb96d36b37c632bf02b45ec5b7fc116) --- .buildkite/embedding.yml | 34 ++++++++++++++++++++++++++++++++++ .buildkite/llvm_passes.yml | 14 ++++++++------ .buildkite/pipeline.yml | 2 ++ .buildkite/whitespace.yml | 24 ++++++++++++++++++++++++ 4 files changed, 68 insertions(+), 6 deletions(-) create mode 100644 .buildkite/embedding.yml create mode 100644 .buildkite/whitespace.yml diff --git a/.buildkite/embedding.yml b/.buildkite/embedding.yml new file mode 100644 index 0000000000000..a7cd2611033e5 --- /dev/null +++ b/.buildkite/embedding.yml @@ -0,0 +1,34 @@ +# These steps should only run on `sandbox.jl` machines, not `docker`-isolated ones +# since we need nestable sandboxing. The rootfs images being used here are built from +# the `.buildkite/rootfs_images/llvm-passes.jl` file. +agents: + queue: "julia" + # Only run on `sandbox.jl` machines (not `docker`-isolated ones) since we need nestable sandboxing + sandbox.jl: "true" + os: "linux" + +steps: + - label: "Run embedding tests" + key: embedding + plugins: + - JuliaCI/julia#v1: + version: 1.6 + - staticfloat/sandbox#v1: + rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v1/llvm-passes.tar.gz + rootfs_treehash: "f3ed53f159e8f13edfba8b20ebdb8ece73c1b8a8" + uid: 1000 + gid: 1000 + commands: | + prefix="/tmp/prefix" + echo "+++ Build julia, deploy to $${prefix}" + make -j$${JULIA_NUM_CORES} JULIA_PRECOMPILE=0 prefix=$${prefix} install + + embedding_output="/tmp/embedding-test" + echo "+++ Run embedding tests, deploy to $${embedding_output}" + mkdir -p "$${embedding_output}" + make -j$${JULIA_NUM_CORES} -C test/embedding JULIA="$${prefix}/bin/julia" BIN="$${embedding_output}" + + timeout_in_minutes: 60 + notify: + - github_commit_status: + context: "embedding" diff --git a/.buildkite/llvm_passes.yml b/.buildkite/llvm_passes.yml index 862f748c18499..7beb30e418bb2 100644 --- a/.buildkite/llvm_passes.yml +++ b/.buildkite/llvm_passes.yml @@ -9,6 +9,7 @@ agents: steps: - label: "analyzegc" + key: analyzegc plugins: - JuliaCI/julia#v1: version: 1.6 @@ -17,13 +18,14 @@ steps: rootfs_treehash: "f3ed53f159e8f13edfba8b20ebdb8ece73c1b8a8" commands: | echo "--- Install in-tree LLVM dependencies" - make -j 6 -C deps install-llvm install-clang install-llvm-tools install-libuv install-utf8proc install-unwind + make -j$${JULIA_NUM_CORES} -C deps install-llvm install-clang install-llvm-tools install-libuv install-utf8proc install-unwind echo "+++ run clangsa/analyzegc" - make -j 6 -C test/clangsa - make -j 6 -C src analyzegc + make -j$${JULIA_NUM_CORES} -C test/clangsa + make -j$${JULIA_NUM_CORES} -C src analyzegc timeout_in_minutes: 60 - label: "llvmpasses" + key: llvmpasses plugins: - JuliaCI/julia#v1: version: 1.6 @@ -34,7 +36,7 @@ steps: gid: 1000 commands: | echo "+++ run llvmpasses" - make -j 6 release - make -j 6 -C src install-analysis-deps - make -j 6 -C test/llvmpasses + make -j$${JULIA_NUM_CORES} release JULIA_PRECOMPILE=0 + make -j$${JULIA_NUM_CORES} -C src install-analysis-deps + make -j$${JULIA_NUM_CORES} -C test/llvmpasses timeout_in_minutes: 60 diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index d76f3fd77bd4f..0dee5f2aaa3f7 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -14,6 +14,8 @@ steps: - label: ":buildkite: Launch unsigned pipelines" commands: | + buildkite-agent pipeline upload .buildkite/whitespace.yml buildkite-agent pipeline upload .buildkite/llvm_passes.yml + buildkite-agent pipeline upload .buildkite/embedding.yml agents: queue: julia diff --git a/.buildkite/whitespace.yml b/.buildkite/whitespace.yml new file mode 100644 index 0000000000000..94dcac590a8ca --- /dev/null +++ b/.buildkite/whitespace.yml @@ -0,0 +1,24 @@ +# These steps should only run on `sandbox.jl` machines, not `docker`-isolated ones +# since we need nestable sandboxing. The rootfs images being used here are built from +# the `.buildkite/rootfs_images/llvm-passes.jl` file. +agents: + queue: "julia" + # Only run on `sandbox.jl` machines (not `docker`-isolated ones) since we need nestable sandboxing + sandbox.jl: "true" + os: "linux" + +steps: + - label: "Check whitespace" + key: whitespace + plugins: + - JuliaCI/julia#v1: + version: 1.6 + - staticfloat/sandbox#v1: + rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v1/llvm-passes.tar.gz + rootfs_treehash: "f3ed53f159e8f13edfba8b20ebdb8ece73c1b8a8" + commands: | + make -j$${JULIA_NUM_CORES} check-whitespace + timeout_in_minutes: 10 + notify: + - github_commit_status: + context: "whitespace" From 470d4463b61ab70df6ba0319a28a398f5eb6bdcc Mon Sep 17 00:00:00 2001 From: Elliot Saba Date: Tue, 6 Jul 2021 20:30:34 -0700 Subject: [PATCH 08/74] Comment out signed pipeline test (#41493) * Comment out signed pipeline test This is confirmed working, so let's comment it out until it's actually used by a codesigning step or similar. * Specifically notify llvm passes (cherry picked from commit f2d73006fbffbe91d00f9c32f5c9a1082e255648) --- .buildkite/0_webui.yml | 6 +++--- .buildkite/llvm_passes.yml | 6 ++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.buildkite/0_webui.yml b/.buildkite/0_webui.yml index d5ba4e0ea7cf9..aed6a5e59d9c3 100644 --- a/.buildkite/0_webui.yml +++ b/.buildkite/0_webui.yml @@ -19,6 +19,6 @@ steps: # Our signed pipelines must have a `signature` or `signature_file` parameter that # verifies the treehash of the pipeline itself and the inputs listed in `inputs` - signed_pipelines: - - pipeline: .buildkite/signed_pipeline_test.yml - signature: "U2FsdGVkX18aZgryp6AJTArgD2uOnVWyFFGVOP5qsY4WbGQ/LVAcYiMEp9cweV+2iht+vmEF949CuuGTeQPA1fKlhPwkG3nZ688752DUB6en9oM2nuL31NoDKWHhpygZ" + #signed_pipelines: + # - pipeline: .buildkite/signed_pipeline_test.yml + # signature: "U2FsdGVkX18aZgryp6AJTArgD2uOnVWyFFGVOP5qsY4WbGQ/LVAcYiMEp9cweV+2iht+vmEF949CuuGTeQPA1fKlhPwkG3nZ688752DUB6en9oM2nuL31NoDKWHhpygZ" diff --git a/.buildkite/llvm_passes.yml b/.buildkite/llvm_passes.yml index 7beb30e418bb2..27611a02b8391 100644 --- a/.buildkite/llvm_passes.yml +++ b/.buildkite/llvm_passes.yml @@ -23,6 +23,9 @@ steps: make -j$${JULIA_NUM_CORES} -C test/clangsa make -j$${JULIA_NUM_CORES} -C src analyzegc timeout_in_minutes: 60 + notify: + - github_commit_status: + context: "analyzegc" - label: "llvmpasses" key: llvmpasses @@ -40,3 +43,6 @@ steps: make -j$${JULIA_NUM_CORES} -C src install-analysis-deps make -j$${JULIA_NUM_CORES} -C test/llvmpasses timeout_in_minutes: 60 + notify: + - github_commit_status: + context: "llvm passes" From 4f1fa2fac8a0356e4bad298ce118de1f4b488060 Mon Sep 17 00:00:00 2001 From: Elliot Saba Date: Tue, 6 Jul 2021 23:02:58 -0700 Subject: [PATCH 09/74] Streamline buildkite configuration a bit (#41494) * Add `/cache/repos` as a mapping into the CI sandbox This should allow `git` to find its cached objects properly, which should silence the warnings on CI, and also give us the proper git version info within buildkite builds * Break up `llvmpasses` output a bit * Provide `/cache/repos` for `whitespace` as well * Give a positive message if whitespace check passes It's a little unnerving to have a silent command block in buildkite, so let's output a success message if everything is on the up-and-up (cherry picked from commit 460e981de68169acea23cbe768ea4f8be50d7b85) --- .buildkite/embedding.yml | 3 +++ .buildkite/llvm_passes.yml | 9 ++++++++- .buildkite/whitespace.yml | 2 ++ contrib/check-whitespace.sh | 2 ++ 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/.buildkite/embedding.yml b/.buildkite/embedding.yml index a7cd2611033e5..faffeb1f7cc87 100644 --- a/.buildkite/embedding.yml +++ b/.buildkite/embedding.yml @@ -18,6 +18,9 @@ steps: rootfs_treehash: "f3ed53f159e8f13edfba8b20ebdb8ece73c1b8a8" uid: 1000 gid: 1000 + workspaces: + # Include `/cache/repos` so that our `git` version introspection works. + - "/cache/repos:/cache/repos" commands: | prefix="/tmp/prefix" echo "+++ Build julia, deploy to $${prefix}" diff --git a/.buildkite/llvm_passes.yml b/.buildkite/llvm_passes.yml index 27611a02b8391..b4311f689d089 100644 --- a/.buildkite/llvm_passes.yml +++ b/.buildkite/llvm_passes.yml @@ -16,6 +16,9 @@ steps: - staticfloat/sandbox#v1: rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v1/llvm-passes.tar.gz rootfs_treehash: "f3ed53f159e8f13edfba8b20ebdb8ece73c1b8a8" + workspaces: + # Include `/cache/repos` so that our `git` version introspection works. + - "/cache/repos:/cache/repos" commands: | echo "--- Install in-tree LLVM dependencies" make -j$${JULIA_NUM_CORES} -C deps install-llvm install-clang install-llvm-tools install-libuv install-utf8proc install-unwind @@ -37,10 +40,14 @@ steps: rootfs_treehash: "f3ed53f159e8f13edfba8b20ebdb8ece73c1b8a8" uid: 1000 gid: 1000 + workspaces: + - "/cache/repos:/cache/repos" commands: | - echo "+++ run llvmpasses" + echo "--- make release" make -j$${JULIA_NUM_CORES} release JULIA_PRECOMPILE=0 + echo "--- make src/install-analysis-deps" make -j$${JULIA_NUM_CORES} -C src install-analysis-deps + echo "+++ make test/llvmpasses" make -j$${JULIA_NUM_CORES} -C test/llvmpasses timeout_in_minutes: 60 notify: diff --git a/.buildkite/whitespace.yml b/.buildkite/whitespace.yml index 94dcac590a8ca..37fa66f75a3d9 100644 --- a/.buildkite/whitespace.yml +++ b/.buildkite/whitespace.yml @@ -16,6 +16,8 @@ steps: - staticfloat/sandbox#v1: rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v1/llvm-passes.tar.gz rootfs_treehash: "f3ed53f159e8f13edfba8b20ebdb8ece73c1b8a8" + workspaces: + - "/cache/repos:/cache/repos" commands: | make -j$${JULIA_NUM_CORES} check-whitespace timeout_in_minutes: 10 diff --git a/contrib/check-whitespace.sh b/contrib/check-whitespace.sh index c380d7bdd2969..ff5bd24ab2cbe 100755 --- a/contrib/check-whitespace.sh +++ b/contrib/check-whitespace.sh @@ -35,3 +35,5 @@ if git --no-pager grep --color -n --full-name -e ' $' -- $file_patterns; then echo "and then a forced push of the correct branch" exit 1 fi + +echo "Whitespace check found no issues" From 09a592b0662c7dc5ee2174248420b0de3f97cd3e Mon Sep 17 00:00:00 2001 From: Benjamin Lorenz Date: Wed, 7 Jul 2021 14:24:07 +0200 Subject: [PATCH 10/74] [openblas] fix make targets for applying patches (#41501) when building with USE_BINARYBUILDER=0 (cherry picked from commit 19ecf0078b2fdfb64bc14455abff81c02a2d64e2) --- deps/openblas.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deps/openblas.mk b/deps/openblas.mk index d86663efcbde7..a1ce15100ac4c 100644 --- a/deps/openblas.mk +++ b/deps/openblas.mk @@ -108,12 +108,12 @@ $(BUILDDIR)/$(OPENBLAS_SRC_DIR)/openblas-exshift.patch-applied: $(BUILDDIR)/$(OP patch -p1 -f < $(SRCDIR)/patches/openblas-exshift.patch echo 1 > $@ -$(BUILDDIR)/$(OPENBLAS_SRC_DIR)/openblas-filter-out-mavx-flag-on-zgemm-kernels.patch-applied: $(BUILDDIR)/$(OPENBLAS_SRC_DIR)/openblas-openblas-exshift.patch-applied +$(BUILDDIR)/$(OPENBLAS_SRC_DIR)/openblas-filter-out-mavx-flag-on-zgemm-kernels.patch-applied: $(BUILDDIR)/$(OPENBLAS_SRC_DIR)/openblas-exshift.patch-applied cd $(BUILDDIR)/$(OPENBLAS_SRC_DIR) && \ patch -p1 -f < $(SRCDIR)/patches/openblas-filter-out-mavx-flag-on-zgemm-kernels.patch echo 1 > $@ -$(BUILDDIR)/$(OPENBLAS_SRC_DIR)/openblas-Only-filter-out-mavx-on-Sandybridge.patch-applied: $(BUILDDIR)/$(OPENBLAS_SRC_DIR)/openblas-filter-out-mavx-flag-on-zgemm-kernels.patch +$(BUILDDIR)/$(OPENBLAS_SRC_DIR)/openblas-Only-filter-out-mavx-on-Sandybridge.patch-applied: $(BUILDDIR)/$(OPENBLAS_SRC_DIR)/openblas-filter-out-mavx-flag-on-zgemm-kernels.patch-applied cd $(BUILDDIR)/$(OPENBLAS_SRC_DIR) && \ patch -p1 -f < $(SRCDIR)/patches/openblas-Only-filter-out-mavx-on-Sandybridge.patch echo 1 > $@ From db05faee3f5f8d81f883f7574bc9417fd06894a2 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Wed, 7 Jul 2021 23:09:43 +0900 Subject: [PATCH 11/74] improve some inferrabilities (#41495) (cherry picked from commit 8efdf854448edc2b52dd4bfe1825f940edff15ce) --- base/errorshow.jl | 3 +-- base/process.jl | 9 +++++---- base/toml_parser.jl | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/base/errorshow.jl b/base/errorshow.jl index 1e03996e410ea..641cf5f2cdf4b 100644 --- a/base/errorshow.jl +++ b/base/errorshow.jl @@ -222,7 +222,7 @@ function showerror(io::IO, ex::MethodError) arg_types = (is_arg_types ? ex.args : typesof(ex.args...))::DataType f = ex.f meth = methods_including_ambiguous(f, arg_types) - if length(meth) > 1 + if isa(meth, MethodList) && length(meth) > 1 return showerror_ambiguous(io, meth, f, arg_types) end arg_types_param::SimpleVector = arg_types.parameters @@ -898,4 +898,3 @@ function show(io::IO, ::MIME"text/plain", stack::ExceptionStack) show_exception_stack(io, stack) end show(io::IO, stack::ExceptionStack) = show(io, MIME("text/plain"), stack) - diff --git a/base/process.jl b/base/process.jl index 89ea68a9444c9..b3ec79fa1ab4e 100644 --- a/base/process.jl +++ b/base/process.jl @@ -84,15 +84,16 @@ const SpawnIOs = Vector{Any} # convenience name for readability for io in stdio] handle = Libc.malloc(_sizeof_uv_process) disassociate_julia_struct(handle) # ensure that data field is set to C_NULL + (; exec, flags, env, dir) = cmd err = ccall(:jl_spawn, Int32, (Cstring, Ptr{Cstring}, Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Tuple{Cint, UInt}}, Int, UInt32, Ptr{Cstring}, Cstring, Ptr{Cvoid}), - file, cmd.exec, loop, handle, + file, exec, loop, handle, iohandles, length(iohandles), - cmd.flags, - cmd.env === nothing ? C_NULL : cmd.env, - isempty(cmd.dir) ? C_NULL : cmd.dir, + flags, + env === nothing ? C_NULL : env, + isempty(dir) ? C_NULL : dir, @cfunction(uv_return_spawn, Cvoid, (Ptr{Cvoid}, Int64, Int32))) if err != 0 ccall(:jl_forceclose_uv, Cvoid, (Ptr{Cvoid},), handle) # will call free on handle eventually diff --git a/base/toml_parser.jl b/base/toml_parser.jl index 8fcfc4ca0c29c..4b2af426429a0 100644 --- a/base/toml_parser.jl +++ b/base/toml_parser.jl @@ -323,7 +323,7 @@ function Base.showerror(io::IO, err::ParserError) # In this case we want the arrow to point one character pos = err.pos::Int err.type == ErrUnexpectedEofExpectedValue && (pos += 1) - str1, err1 = point_to_line(err.str, pos, pos, io) + str1, err1 = point_to_line(err.str::String, pos, pos, io) @static if VERSION <= v"1.6.0-DEV.121" # See https://github.com/JuliaLang/julia/issues/36015 format_fixer = get(io, :color, false) == true ? "\e[0m" : "" From ac93888917394d4f18dbba3a406d5132d858b6e8 Mon Sep 17 00:00:00 2001 From: Simeon Schaub Date: Wed, 7 Jul 2021 17:40:33 +0200 Subject: [PATCH 12/74] fix #41489: inference of `+(::Rational, Rational)` (#41491) * fix #41489: inference of `+(::Rational, Rational)` * implement review comments (cherry picked from commit cf4e1c458c109959300e4db308a71599de582ca9) --- base/rational.jl | 4 ++-- test/rational.jl | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/base/rational.jl b/base/rational.jl index ab4e7d6d0abbd..23c9298962f53 100644 --- a/base/rational.jl +++ b/base/rational.jl @@ -280,7 +280,7 @@ function -(x::Rational{T}) where T<:Unsigned end function +(x::Rational, y::Rational) - xp, yp = promote(x, y) + xp, yp = promote(x, y)::NTuple{2,Rational} if isinf(x) && x == y return xp end @@ -289,7 +289,7 @@ function +(x::Rational, y::Rational) end function -(x::Rational, y::Rational) - xp, yp = promote(x, y) + xp, yp = promote(x, y)::NTuple{2,Rational} if isinf(x) && x == -y return xp end diff --git a/test/rational.jl b/test/rational.jl index 24b99cdc8b6d9..a329a1ac5f93d 100644 --- a/test/rational.jl +++ b/test/rational.jl @@ -622,3 +622,11 @@ end @testset "Rational{T} with non-concrete T (issue #41222)" begin @test @inferred(Rational{Integer}(2,3)) isa Rational{Integer} end + +@testset "issue #41489" begin + @test Core.Compiler.return_type(+, NTuple{2, Rational}) == Rational + @test Core.Compiler.return_type(-, NTuple{2, Rational}) == Rational + + A=Rational[1 1 1; 2 2 2; 3 3 3] + @test @inferred(A*A) isa Matrix{Rational} +end From 08f11dbf3026b0fe9fa4f100f70a73b43dc19a3b Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Wed, 7 Jul 2021 12:24:23 -0700 Subject: [PATCH 13/74] Initialize n_uninitialized for Symbol and SimpleVector (#41496) (cherry picked from commit 6240d352f1bed2671b0477584a8b4082c5fb38da) --- src/jltypes.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/jltypes.c b/src/jltypes.c index 886abadb046e0..1ae49c0a32eab 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -2016,6 +2016,7 @@ void jl_init_types(void) JL_GC_DISABLED jl_symbol_type->name->mt = jl_nonfunction_mt; jl_symbol_type->super = jl_any_type; jl_symbol_type->parameters = jl_emptysvec; + jl_symbol_type->name->n_uninitialized = 0; jl_symbol_type->name->names = jl_emptysvec; jl_symbol_type->types = jl_emptysvec; jl_symbol_type->size = 0; @@ -2026,6 +2027,7 @@ void jl_init_types(void) JL_GC_DISABLED jl_simplevector_type->name->mt = jl_nonfunction_mt; jl_simplevector_type->super = jl_any_type; jl_simplevector_type->parameters = jl_emptysvec; + jl_simplevector_type->name->n_uninitialized = 0; jl_simplevector_type->name->names = jl_emptysvec; jl_simplevector_type->types = jl_emptysvec; jl_precompute_memoized_dt(jl_simplevector_type, 1); From 54017220337914c5d2e6e36837b6ddd9f657b9f9 Mon Sep 17 00:00:00 2001 From: Nicholas Bauer Date: Wed, 7 Jul 2021 16:53:23 -0400 Subject: [PATCH 14/74] `hvncat`: Better handling of 0- and 1-length dims/shape args (#41197) (cherry picked from commit 7bc38a0d937fb30cd19753a400913fca1046d37f) --- base/abstractarray.jl | 67 ++++++++++++++++++++++++++++++++++--------- test/abstractarray.jl | 64 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 116 insertions(+), 15 deletions(-) diff --git a/base/abstractarray.jl b/base/abstractarray.jl index b438a0ad36339..8a2774c866dbc 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -2129,28 +2129,34 @@ julia> hvncat(((3, 3), (3, 3), (6,)), true, a, b, c, d, e, f) 4 = elements in each 4d slice (4,) => shape = ((2, 1, 1), (3, 1), (4,), (4,)) with `rowfirst` = true """ -hvncat(::Tuple{}, ::Bool) = [] -hvncat(::Tuple{}, ::Bool, xs...) = [] -hvncat(::Tuple{Vararg{Any, 1}}, ::Bool, xs...) = vcat(xs...) # methods assume 2+ dimensions hvncat(dimsshape::Tuple, row_first::Bool, xs...) = _hvncat(dimsshape, row_first, xs...) hvncat(dim::Int, xs...) = _hvncat(dim, true, xs...) -_hvncat(::Union{Tuple, Int}, ::Bool) = [] +_hvncat(dimsshape::Union{Tuple, Int}, row_first::Bool) = _typed_hvncat(Any, dimsshape, row_first) _hvncat(dimsshape::Union{Tuple, Int}, row_first::Bool, xs...) = _typed_hvncat(promote_eltypeof(xs...), dimsshape, row_first, xs...) _hvncat(dimsshape::Union{Tuple, Int}, row_first::Bool, xs::T...) where T<:Number = _typed_hvncat(T, dimsshape, row_first, xs...) _hvncat(dimsshape::Union{Tuple, Int}, row_first::Bool, xs::Number...) = _typed_hvncat(promote_typeof(xs...), dimsshape, row_first, xs...) _hvncat(dimsshape::Union{Tuple, Int}, row_first::Bool, xs::AbstractArray...) = _typed_hvncat(promote_eltype(xs...), dimsshape, row_first, xs...) _hvncat(dimsshape::Union{Tuple, Int}, row_first::Bool, xs::AbstractArray{T}...) where T = _typed_hvncat(T, dimsshape, row_first, xs...) -typed_hvncat(::Type{T}, ::Tuple{}, ::Bool) where T = Vector{T}() -typed_hvncat(::Type{T}, ::Tuple{}, ::Bool, xs...) where T = Vector{T}() -typed_hvncat(T::Type, ::Tuple{Vararg{Any, 1}}, ::Bool, xs...) = typed_vcat(T, xs...) # methods assume 2+ dimensions typed_hvncat(T::Type, dimsshape::Tuple, row_first::Bool, xs...) = _typed_hvncat(T, dimsshape, row_first, xs...) typed_hvncat(T::Type, dim::Int, xs...) = _typed_hvncat(T, Val(dim), xs...) -_typed_hvncat(::Type{T}, ::Tuple{}, ::Bool) where T = Vector{T}() -_typed_hvncat(::Type{T}, ::Tuple{}, ::Bool, xs...) where T = Vector{T}() -_typed_hvncat(::Type{T}, ::Tuple{}, ::Bool, xs::Number...) where T = Vector{T}() +# 1-dimensional hvncat methods + +_typed_hvncat(::Type, ::Val{0}) = _typed_hvncat_0d_only_one() +_typed_hvncat(T::Type, ::Val{0}, x) = fill(convert(T, x)) +_typed_hvncat(T::Type, ::Val{0}, x::Number) = fill(convert(T, x)) +_typed_hvncat(T::Type, ::Val{0}, x::AbstractArray) = convert.(T, x) +_typed_hvncat(::Type, ::Val{0}, ::Any...) = _typed_hvncat_0d_only_one() +_typed_hvncat(::Type, ::Val{0}, ::Number...) = _typed_hvncat_0d_only_one() +_typed_hvncat(::Type, ::Val{0}, ::AbstractArray...) = _typed_hvncat_0d_only_one() + +_typed_hvncat_0d_only_one() = + throw(ArgumentError("a 0-dimensional array may only contain exactly one element")) + +_typed_hvncat(::Type{T}, ::Val{N}) where {T, N} = Array{T, N}(undef, ntuple(x -> 0, Val(N))) + function _typed_hvncat(::Type{T}, dims::Tuple{Vararg{Int, N}}, row_first::Bool, xs::Number...) where {T, N} A = Array{T, N}(undef, dims...) lengtha = length(A) # Necessary to store result because throw blocks are being deoptimized right now, which leads to excessive allocations @@ -2188,14 +2194,13 @@ function hvncat_fill!(A::Array, row_first::Bool, xs::Tuple) end _typed_hvncat(T::Type, dim::Int, ::Bool, xs...) = _typed_hvncat(T, Val(dim), xs...) # catches from _hvncat type promoters -_typed_hvncat(::Type{T}, ::Val) where T = Vector{T}() -_typed_hvncat(T::Type, ::Val{N}, xs::Number...) where N = _typed_hvncat(T, (ntuple(x -> 1, N - 1)..., length(xs)), false, xs...) function _typed_hvncat(::Type{T}, ::Val{N}, as::AbstractArray...) where {T, N} # optimization for arrays that can be concatenated by copying them linearly into the destination # conditions: the elements must all have 1- or 0-length dimensions above N for a ∈ as ndims(a) <= N || all(x -> size(a, x) == 1, (N + 1):ndims(a)) || - return _typed_hvncat(T, (ntuple(x -> 1, N - 1)..., length(as)), false, as...) + return _typed_hvncat(T, (ntuple(x -> 1, N - 1)..., length(as), 1), false, as...) + # the extra 1 is to avoid an infinite cycle end nd = max(N, ndims(as[1])) @@ -2249,6 +2254,31 @@ function _typed_hvncat(::Type{T}, ::Val{N}, as...) where {T, N} return A end + +# 0-dimensional cases for balanced and unbalanced hvncat method + +_typed_hvncat(T::Type, ::Tuple{}, ::Bool, x...) = _typed_hvncat(T, Val(0), x...) +_typed_hvncat(T::Type, ::Tuple{}, ::Bool, x::Number...) = _typed_hvncat(T, Val(0), x...) + + +# balanced dimensions hvncat methods + +_typed_hvncat(T::Type, dims::Tuple{Int}, ::Bool, as...) = _typed_hvncat_1d(T, dims[1], Val(false), as...) +_typed_hvncat(T::Type, dims::Tuple{Int}, ::Bool, as::Number...) = _typed_hvncat_1d(T, dims[1], Val(false), as...) + +function _typed_hvncat_1d(::Type{T}, ds::Int, ::Val{row_first}, as...) where {T, row_first} + lengthas = length(as) + ds > 0 || + throw(ArgumentError("`dimsshape` argument must consist of positive integers")) + lengthas == ds || + throw(ArgumentError("number of elements does not match `dimshape` argument; expected $ds, got $lengthas")) + if row_first + return _typed_hvncat(T, Val(2), as...) + else + return _typed_hvncat(T, Val(1), as...) + end +end + function _typed_hvncat(::Type{T}, dims::Tuple{Vararg{Int, N}}, row_first::Bool, as...) where {T, N} d1 = row_first ? 2 : 1 d2 = row_first ? 1 : 2 @@ -2311,7 +2341,16 @@ function _typed_hvncat(::Type{T}, dims::Tuple{Vararg{Int, N}}, row_first::Bool, return A end -function _typed_hvncat(::Type{T}, shape::Tuple{Vararg{Tuple, N}}, row_first::Bool, as...) where {T, N} + +# unbalanced dimensions hvncat methods + +function _typed_hvncat(T::Type, shape::Tuple{Tuple}, row_first::Bool, xs...) + length(shape[1]) > 0 || + throw(ArgumentError("each level of `shape` argument must have at least one value")) + return _typed_hvncat_1d(T, shape[1][1], Val(row_first), xs...) +end + +function _typed_hvncat(T::Type, shape::NTuple{N, Tuple}, row_first::Bool, as...) where {N} d1 = row_first ? 2 : 1 d2 = row_first ? 1 : 2 shape = collect(shape) # saves allocations later diff --git a/test/abstractarray.jl b/test/abstractarray.jl index 65f9f4efa2cd3..a1c6dd1b22ce7 100644 --- a/test/abstractarray.jl +++ b/test/abstractarray.jl @@ -1342,6 +1342,7 @@ end end end +using Base: typed_hvncat @testset "hvncat" begin a = fill(1, (2,3,2,4,5)) b = fill(2, (1,1,2,4,5)) @@ -1389,7 +1390,68 @@ end @test [v v;;; fill(v, 1, 2)] == fill(v, 1, 2, 2) end - @test_throws BoundsError hvncat(((1, 2), (3,)), false, zeros(Int, 0, 0, 0), 7, 8) + # 0-dimension behaviors + # exactly one argument, placed in an array + # if already an array, copy, with type conversion as necessary + @test_throws ArgumentError hvncat(0) + @test hvncat(0, 1) == fill(1) + @test hvncat(0, [1]) == [1] + @test_throws ArgumentError hvncat(0, 1, 1) + @test_throws ArgumentError typed_hvncat(Float64, 0) + @test typed_hvncat(Float64, 0, 1) == fill(1.0) + @test typed_hvncat(Float64, 0, [1]) == Float64[1.0] + @test_throws ArgumentError typed_hvncat(Float64, 0, 1, 1) + @test_throws ArgumentError hvncat((), true) == [] + @test hvncat((), true, 1) == fill(1) + @test hvncat((), true, [1]) == [1] + @test_throws ArgumentError hvncat((), true, 1, 1) + @test_throws ArgumentError typed_hvncat(Float64, (), true) == Float64[] + @test typed_hvncat(Float64, (), true, 1) == fill(1.0) + @test typed_hvncat(Float64, (), true, [1]) == [1.0] + @test_throws ArgumentError typed_hvncat(Float64, (), true, 1, 1) + + # 1-dimension behaviors + # int form + @test hvncat(1) == [] + @test hvncat(1, 1) == [1] + @test hvncat(1, [1]) == [1] + @test hvncat(1, [1 2; 3 4]) == [1 2; 3 4] + @test hvncat(1, 1, 1) == [1 ; 1] + @test typed_hvncat(Float64, 1) == Float64[] + @test typed_hvncat(Float64, 1, 1) == Float64[1.0] + @test typed_hvncat(Float64, 1, [1]) == Float64[1.0] + @test typed_hvncat(Float64, 1, 1, 1) == Float64[1.0 ; 1.0] + # dims form + @test_throws ArgumentError hvncat((1,), true) + @test hvncat((2,), true, 1, 1) == [1; 1] + @test hvncat((2,), true, [1], [1]) == [1; 1] + @test_throws ArgumentError hvncat((2,), true, 1) + @test typed_hvncat(Float64, (2,), true, 1, 1) == Float64[1.0; 1.0] + @test typed_hvncat(Float64, (2,), true, [1], [1]) == Float64[1.0; 1.0] + @test_throws ArgumentError typed_hvncat(Float64, (2,), true, 1) + # row_first has no effect with just one dimension of the dims form + @test hvncat((2,), false, 1, 1) == [1; 1] + @test typed_hvncat(Float64, (2,), false, 1, 1) == Float64[1.0; 1.0] + # shape form + @test hvncat(((2,),), true, 1, 1) == [1 1] + @test hvncat(((2,),), true, [1], [1]) == [1 1] + @test_throws ArgumentError hvncat(((2,),), true, 1) + @test hvncat(((2,),), false, 1, 1) == [1; 1] + @test hvncat(((2,),), false, [1], [1]) == [1; 1] + @test typed_hvncat(Float64, ((2,),), true, 1, 1) == Float64[1.0 1.0] + @test typed_hvncat(Float64, ((2,),), true, [1], [1]) == Float64[1.0 1.0] + @test_throws ArgumentError typed_hvncat(Float64, ((2,),), true, 1) + @test typed_hvncat(Float64, ((2,),), false, 1, 1) == Float64[1.0; 1.0] + @test typed_hvncat(Float64, ((2,),), false, [1], [1]) == Float64[1.0; 1.0] + + # zero-value behaviors for int form above dimension zero + # e.g. [;;], [;;;], though that isn't valid syntax + @test [] == hvncat(1) isa Array{Any, 1} + @test Array{Any, 2}(undef, 0, 0) == hvncat(2) isa Array{Any, 2} + @test Array{Any, 3}(undef, 0, 0, 0) == hvncat(3) isa Array{Any, 3} + @test Int[] == typed_hvncat(Int, 1) isa Array{Int, 1} + @test Array{Int, 2}(undef, 0, 0) == typed_hvncat(Int, 2) isa Array{Int, 2} + @test Array{Int, 3}(undef, 0, 0, 0) == typed_hvncat(Int, 3) isa Array{Int, 3} end @testset "keepat!" begin From cbb3367fe7941152d65b5ed359e705e0f223fd16 Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Wed, 7 Jul 2021 16:54:52 -0400 Subject: [PATCH 15/74] fix #40773, bug in `summarysize` on arrays of inlined structs with pointers (#41492) (cherry picked from commit c49153dce6c29e9e04cd1b7e4c71ac89c4a64737) --- base/summarysize.jl | 5 +++-- test/misc.jl | 5 +++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/base/summarysize.jl b/base/summarysize.jl index 916214a69f88f..62458dcdc5b97 100644 --- a/base/summarysize.jl +++ b/base/summarysize.jl @@ -120,12 +120,13 @@ function (ss::SummarySize)(obj::Array) if !haskey(ss.seen, datakey) ss.seen[datakey] = true dsize = Core.sizeof(obj) - if isbitsunion(eltype(obj)) + T = eltype(obj) + if isbitsunion(T) # add 1 union selector byte for each element dsize += length(obj) end size += dsize - if !isempty(obj) && !Base.allocatedinline(eltype(obj)) + if !isempty(obj) && (!Base.allocatedinline(T) || (T isa DataType && !Base.datatype_pointerfree(T))) push!(ss.frontier_x, obj) push!(ss.frontier_i, 1) end diff --git a/test/misc.jl b/test/misc.jl index 37c5397b4948f..e765dc9279b86 100644 --- a/test/misc.jl +++ b/test/misc.jl @@ -302,6 +302,11 @@ let vec = vcat(missing, ones(100000)) @test length(unique(summarysize(vec) for i = 1:20)) == 1 end +# issue #40773 +let s = Set(1:100) + @test summarysize([s]) > summarysize(s) +end + # issue #13021 let ex = try Main.x13021 = 0 From afad5f61f405efdea4884bc569278b0b84b015d9 Mon Sep 17 00:00:00 2001 From: Pete Vilter <7341+vilterp@users.noreply.github.com> Date: Wed, 7 Jul 2021 18:58:21 -0400 Subject: [PATCH 16/74] add a GC safepoint in Task.wait (#41441) (cherry picked from commit 97f817a379b0c3c5f9bb803427fe88a018ebfe18) --- base/task.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/base/task.jl b/base/task.jl index e84c344c28d17..0d4e5da4ccfd4 100644 --- a/base/task.jl +++ b/base/task.jl @@ -818,6 +818,7 @@ end end function wait() + GC.safepoint() W = Workqueues[Threads.threadid()] poptask(W) result = try_yieldto(ensure_rescheduled) From 170c2768beff9fdfc1390e47d4327d2ca291a8f1 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Fri, 9 Jul 2021 23:49:13 -0400 Subject: [PATCH 17/74] Null out some GC roots (cherry picked from commit 22c52a1db096b8182ba7d496fe9fb61159cc2b0c) --- src/codegen.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index 3d8ad33516080..9775db39892f7 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -4697,10 +4697,10 @@ static jl_cgval_t emit_expr(jl_codectx_t &ctx, jl_value_t *expr, ssize_t ssaval) std::unique_ptr closure_m; jl_llvm_functions_t closure_decls; - jl_method_instance_t *li; - jl_value_t *closure_t; - jl_tupletype_t *env_t; - jl_svec_t *sig_args; + jl_method_instance_t *li = NULL; + jl_value_t *closure_t = NULL; + jl_tupletype_t *env_t = NULL; + jl_svec_t *sig_args = NULL; JL_GC_PUSH5(&li, &closure_src, &closure_t, &env_t, &sig_args); li = jl_new_method_instance_uninit(); From 4f4fabfd77f71678989ef24b263f3b5fdc2ec42a Mon Sep 17 00:00:00 2001 From: Dilum Aluthge Date: Sun, 11 Jul 2021 01:19:12 -0400 Subject: [PATCH 18/74] CI (Buildkite): use a consistent naming scheme for labels, keys, and commit statuses (#41543) (cherry picked from commit ffc340c07ed15e1b1960ab7c900ef5203e3a0fad) --- .buildkite/embedding.yml | 4 ++-- .buildkite/llvm_passes.yml | 6 +++--- .buildkite/whitespace.yml | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.buildkite/embedding.yml b/.buildkite/embedding.yml index faffeb1f7cc87..5cf6b985573f5 100644 --- a/.buildkite/embedding.yml +++ b/.buildkite/embedding.yml @@ -8,8 +8,8 @@ agents: os: "linux" steps: - - label: "Run embedding tests" - key: embedding + - label: "embedding" + key: "embedding" plugins: - JuliaCI/julia#v1: version: 1.6 diff --git a/.buildkite/llvm_passes.yml b/.buildkite/llvm_passes.yml index b4311f689d089..7453af82c1e73 100644 --- a/.buildkite/llvm_passes.yml +++ b/.buildkite/llvm_passes.yml @@ -9,7 +9,7 @@ agents: steps: - label: "analyzegc" - key: analyzegc + key: "analyzegc" plugins: - JuliaCI/julia#v1: version: 1.6 @@ -31,7 +31,7 @@ steps: context: "analyzegc" - label: "llvmpasses" - key: llvmpasses + key: "llvmpasses" plugins: - JuliaCI/julia#v1: version: 1.6 @@ -52,4 +52,4 @@ steps: timeout_in_minutes: 60 notify: - github_commit_status: - context: "llvm passes" + context: "llvmpasses" diff --git a/.buildkite/whitespace.yml b/.buildkite/whitespace.yml index 37fa66f75a3d9..bd625e855c5b5 100644 --- a/.buildkite/whitespace.yml +++ b/.buildkite/whitespace.yml @@ -8,8 +8,8 @@ agents: os: "linux" steps: - - label: "Check whitespace" - key: whitespace + - label: "whitespace" + key: "whitespace" plugins: - JuliaCI/julia#v1: version: 1.6 From 663415f9eb9770ea0bfa8a7bf1932a8ba72d5e66 Mon Sep 17 00:00:00 2001 From: Dilum Aluthge Date: Sun, 11 Jul 2021 17:01:58 -0400 Subject: [PATCH 19/74] CI: Add more Debian packages to the `llvm-passes` rootfs image (#41544) * Add `less` to the `llvm-passes` rootfs image Also, sort the entries of `packages` in alphabetical order. * Update llvm-passes.jl (cherry picked from commit 516af1b182e38aefd4223b740e4c6fef7aea4797) --- .buildkite/rootfs_images/llvm-passes.jl | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/.buildkite/rootfs_images/llvm-passes.jl b/.buildkite/rootfs_images/llvm-passes.jl index 17c9588f75c9e..2d9e47ba4f0fc 100755 --- a/.buildkite/rootfs_images/llvm-passes.jl +++ b/.buildkite/rootfs_images/llvm-passes.jl @@ -8,18 +8,20 @@ include("rootfs_utils.jl") # Build debian-based image with the following extra packages: packages = [ + "bash", "build-essential", + "cmake", + "curl", + "gfortran", + "git", + "less", "libatomic1", + "m4", + "perl", + "pkg-config", "python", "python3", - "gfortran", - "perl", "wget", - "m4", - "cmake", - "pkg-config", - "curl", - "git", ] tarball_path = debootstrap("llvm-passes"; packages) From fd85e6b1742cedf4f99f9a8e9747b4a76b76ae59 Mon Sep 17 00:00:00 2001 From: Michael Abbott <32575566+mcabbott@users.noreply.github.com> Date: Mon, 12 Jul 2021 05:36:42 -0400 Subject: [PATCH 20/74] change .* to * in fallback 3-arg `*` methods (#41545) (cherry picked from commit e3a06c495df00ed6b83596b1a34855957d4beff7) --- stdlib/LinearAlgebra/src/matmul.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/stdlib/LinearAlgebra/src/matmul.jl b/stdlib/LinearAlgebra/src/matmul.jl index 10e6e7722f414..82f44c8e559fc 100644 --- a/stdlib/LinearAlgebra/src/matmul.jl +++ b/stdlib/LinearAlgebra/src/matmul.jl @@ -1141,7 +1141,7 @@ end # Fast path for two arrays * one scalar is opt-in, via mat_vec_scalar and mat_mat_scalar. -mat_vec_scalar(A, x, γ) = A * (x .* γ) # fallback +mat_vec_scalar(A, x, γ) = A * (x * γ) # fallback mat_vec_scalar(A::StridedMaybeAdjOrTransMat, x::StridedVector, γ) = _mat_vec_scalar(A, x, γ) mat_vec_scalar(A::AdjOrTransAbsVec, x::StridedVector, γ) = (A * x) * γ @@ -1151,7 +1151,7 @@ function _mat_vec_scalar(A, x, γ) mul!(C, A, x, γ, false) end -mat_mat_scalar(A, B, γ) = (A*B) .* γ # fallback +mat_mat_scalar(A, B, γ) = (A*B) * γ # fallback mat_mat_scalar(A::StridedMaybeAdjOrTransMat, B::StridedMaybeAdjOrTransMat, γ) = _mat_mat_scalar(A, B, γ) @@ -1161,11 +1161,11 @@ function _mat_mat_scalar(A, B, γ) mul!(C, A, B, γ, false) end -mat_mat_scalar(A::AdjointAbsVec, B, γ) = (γ' .* (A * B)')' # preserving order, adjoint reverses +mat_mat_scalar(A::AdjointAbsVec, B, γ) = (γ' * (A * B)')' # preserving order, adjoint reverses mat_mat_scalar(A::AdjointAbsVec{<:RealOrComplex}, B::StridedMaybeAdjOrTransMat{<:RealOrComplex}, γ::RealOrComplex) = mat_vec_scalar(B', A', γ')' -mat_mat_scalar(A::TransposeAbsVec, B, γ) = transpose(γ .* transpose(A * B)) +mat_mat_scalar(A::TransposeAbsVec, B, γ) = transpose(γ * transpose(A * B)) mat_mat_scalar(A::TransposeAbsVec{<:RealOrComplex}, B::StridedMaybeAdjOrTransMat{<:RealOrComplex}, γ::RealOrComplex) = transpose(mat_vec_scalar(transpose(B), transpose(A), γ)) From c85a571a8daf2ce33bb529efe7bf051b7d9a5438 Mon Sep 17 00:00:00 2001 From: Dilum Aluthge Date: Mon, 12 Jul 2021 13:53:43 -0400 Subject: [PATCH 21/74] CI (Buildkite): rootfs_images: allow user to override the default value of `tag_name` (#41549) (cherry picked from commit a9232d67203e6f1aca4934318d86f85cad50550b) --- .buildkite/rootfs_images/llvm-passes.jl | 2 +- .buildkite/rootfs_images/rootfs_utils.jl | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.buildkite/rootfs_images/llvm-passes.jl b/.buildkite/rootfs_images/llvm-passes.jl index 2d9e47ba4f0fc..3df2de49522c9 100755 --- a/.buildkite/rootfs_images/llvm-passes.jl +++ b/.buildkite/rootfs_images/llvm-passes.jl @@ -26,4 +26,4 @@ packages = [ tarball_path = debootstrap("llvm-passes"; packages) # Upload it -upload_rootfs_image(tarball_path) +upload_rootfs_image(tarball_path; tag_name = "v1") diff --git a/.buildkite/rootfs_images/rootfs_utils.jl b/.buildkite/rootfs_images/rootfs_utils.jl index 7df224a31f740..3412fbcc03f56 100644 --- a/.buildkite/rootfs_images/rootfs_utils.jl +++ b/.buildkite/rootfs_images/rootfs_utils.jl @@ -82,9 +82,10 @@ function debootstrap(name::String; release::String="buster", variant::String="mi return tarball_path end -function upload_rootfs_image(tarball_path::String; github_repo::String="JuliaCI/rootfs-images") +function upload_rootfs_image(tarball_path::String; + github_repo::String="JuliaCI/rootfs-images", + tag_name::String="v1") # Upload it to `github_repo` - tag_name = "v1" tarball_url = "https://github.com/$(github_repo)/releases/download/$(tag_name)/$(basename(tarball_path))" @info("Uploading to $(github_repo)@$(tag_name)", tarball_url) run(`$(ghr_jll.ghr()) -u $(dirname(github_repo)) -r $(basename(github_repo)) -replace $(tag_name) $(tarball_path)`) From 9ae40befb09edc79bd7d638c2cba432f91b06bb5 Mon Sep 17 00:00:00 2001 From: Elliot Saba Date: Mon, 12 Jul 2021 16:17:15 -0700 Subject: [PATCH 22/74] Fix `get-task-allow` entitlement (#41559) We had apparently misspelled this entitlement, not allowing `lldb` to attach to official macOS builds. (cherry picked from commit ad6740b4f27ddc5a32bc3ee7496383b2fa3edfea) --- contrib/mac/app/Entitlements.plist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/mac/app/Entitlements.plist b/contrib/mac/app/Entitlements.plist index b84dccb00f95c..95c1a02d58958 100644 --- a/contrib/mac/app/Entitlements.plist +++ b/contrib/mac/app/Entitlements.plist @@ -4,7 +4,7 @@ com.apple.security.automation.apple-events - com.apple.security.cs.get-task-allow + com.apple.security.get-task-allow com.apple.security.cs.allow-dyld-environment-variables From 91789413234a1e358f995e3c25f989df581291a1 Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Tue, 13 Jul 2021 10:29:53 +0200 Subject: [PATCH 23/74] add a test for #41096 (#41556) (cherry picked from commit d7329038feb207997b9a6d969c5c8f11d37680d5) --- test/compiler/codegen.jl | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/test/compiler/codegen.jl b/test/compiler/codegen.jl index f232b246a9fc9..cc6095b867d41 100644 --- a/test/compiler/codegen.jl +++ b/test/compiler/codegen.jl @@ -597,3 +597,35 @@ f41438(y) = y[].x # issue #41157 f41157(a, b) = a[1] = b[1] @test_throws BoundsError f41157(Tuple{Int}[], Tuple{Union{}}[]) + +# issue #41096 +struct Modulate41096{M<:Union{Function, Val{true}, Val{false}}, id} + modulate::M + Modulate41096(id::Symbol, modulate::Function) = new{typeof(modulate), id}(modulate) + Modulate41096(id::Symbol, modulate::Bool=true) = new{Val{modulate}, id}(modulate|>Val) +end +@inline ismodulatable41096(modulate::Modulate41096) = ismodulatable41096(typeof(modulate)) +@inline ismodulatable41096(::Type{<:Modulate41096{Val{B}}}) where B = B +@inline ismodulatable41096(::Type{<:Modulate41096{<:Function}}) = true + +mutable struct Term41096{I, M<:Modulate41096} + modulate::M + Term41096{I}(modulate::Modulate41096) where I = new{I, typeof(modulate)}(modulate) +end +@inline ismodulatable41096(term::Term41096) = ismodulatable41096(typeof(term)) +@inline ismodulatable41096(::Type{<:Term41096{I, M} where I}) where M = ismodulatable41096(M) + +function newexpand41096(gen, name::Symbol) + flag = ismodulatable41096(getfield(gen, name)) + if flag + return true + else + return false + end +end + +t41096 = Term41096{:t}(Modulate41096(:t, false)) +μ41096 = Term41096{:μ}(Modulate41096(:μ, false)) +U41096 = Term41096{:U}(Modulate41096(:U, false)) + +@test !newexpand41096((t=t41096, μ=μ41096, U=U41096), :U) From e4217a4e3804bfd2259f65a36579d0020241917c Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Tue, 13 Jul 2021 17:45:50 -0400 Subject: [PATCH 24/74] fix another bug in circular type detection (#41516) Co-authored-by: Jeff Bezanson (cherry picked from commit 1c92e0de7a0c9fea963bd622a63d37f680e8d996) --- src/builtins.c | 35 ++++++++++++++++++++++++++++------- test/core.jl | 13 +++++++++++-- 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/src/builtins.c b/src/builtins.c index f40d694d23529..7ef93faaa6368 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -1487,22 +1487,38 @@ static int equiv_field_types(jl_value_t *old, jl_value_t *ft) return 1; } +// If a field can reference its enclosing type, then the inlining +// recursive depth is not statically bounded for some layouts, so we cannot +// inline it. The only way fields can reference this type (due to +// syntax-enforced restrictions) is via being passed as a type parameter. Thus +// we can conservatively check this by examining only the parameters of the +// dependent types. +// affects_layout is a hack introduced by #35275 to workaround a problem +// introduced by #34223: it checks whether we will potentially need to +// compute the layout of the object before we have fully computed the types of +// the fields during recursion over the allocation of the parameters for the +// field types (of the concrete subtypes) static int references_name(jl_value_t *p, jl_typename_t *name, int affects_layout) JL_NOTSAFEPOINT { if (jl_is_uniontype(p)) return references_name(((jl_uniontype_t*)p)->a, name, affects_layout) || references_name(((jl_uniontype_t*)p)->b, name, affects_layout); if (jl_is_unionall(p)) - return references_name((jl_value_t*)((jl_unionall_t*)p)->var, name, 0) || + return references_name((jl_value_t*)((jl_unionall_t*)p)->var->lb, name, 0) || + references_name((jl_value_t*)((jl_unionall_t*)p)->var->ub, name, 0) || references_name(((jl_unionall_t*)p)->body, name, affects_layout); if (jl_is_typevar(p)) - return references_name(((jl_tvar_t*)p)->ub, name, 0) || - references_name(((jl_tvar_t*)p)->lb, name, 0); + return 0; // already checked by unionall, if applicable if (jl_is_datatype(p)) { jl_datatype_t *dp = (jl_datatype_t*)p; if (affects_layout && dp->name == name) return 1; - affects_layout = dp->types == NULL || jl_svec_len(dp->types) != 0; + // affects_layout checks whether we will need to attempt to layout this + // type (based on whether all copies of it have the same layout) in + // that case, we still need to check the recursive parameters for + // layout recursion happening also, but we know it won't itself cause + // problems for the layout computation + affects_layout = ((jl_datatype_t*)jl_unwrap_unionall(dp->name->wrapper))->layout == NULL; size_t i, l = jl_nparams(p); for (i = 0; i < l; i++) { if (references_name(jl_tparam(p, i), name, affects_layout)) @@ -1537,16 +1553,21 @@ JL_CALLABLE(jl_f__typebody) else { dt->types = (jl_svec_t*)ft; jl_gc_wb(dt, ft); - if (!dt->name->mutabl) { - dt->name->mayinlinealloc = 1; + // If a supertype can reference the same type, then we may not be + // able to compute the layout of the object before needing to + // publish it, so we must assume it cannot be inlined, if that + // check passes, then we also still need to check the fields too. + if (!dt->name->mutabl && !references_name((jl_value_t*)dt->super, dt->name, 1)) { + int mayinlinealloc = 1; size_t i, nf = jl_svec_len(ft); for (i = 0; i < nf; i++) { jl_value_t *fld = jl_svecref(ft, i); if (references_name(fld, dt->name, 1)) { - dt->name->mayinlinealloc = 0; + mayinlinealloc = 0; break; } } + dt->name->mayinlinealloc = mayinlinealloc; } } } diff --git a/test/core.jl b/test/core.jl index e0be3b109cb44..020722fd5f70b 100644 --- a/test/core.jl +++ b/test/core.jl @@ -7217,8 +7217,17 @@ end struct B33954 x::Q33954{B33954} end -@test_broken isbitstype(Tuple{B33954}) -@test_broken isbitstype(B33954) +@test isbitstype(Tuple{B33954}) +@test isbitstype(B33954) + +struct A41503{d} + e::d +end +struct B41503{j,k} <: AbstractArray{A41503{B41503{Any,k}},Any} + l::k +end +@test !isbitstype(B41503{Any,Any}) +@test_broken isbitstype(B41503{Any,Int}) struct B40050 <: Ref{Tuple{B40050}} end From 456fb2b014dc9c648a79018626bd9a54ec3769e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mos=C3=A8=20Giordano?= Date: Wed, 14 Jul 2021 18:02:47 +0100 Subject: [PATCH 25/74] [deps] Replace `-L` option to `xargs` with `-n` (#41583) Busybox `xargs` doesn't support `-L` option, so building Julia fails on Alpine Linux for example (cherry picked from commit da28c17d9f9401ff4e9bd1b6e29e09ef735091d1) --- deps/tools/bb-install.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/tools/bb-install.mk b/deps/tools/bb-install.mk index 5c18ddee0bfce..781d66f1c5dda 100644 --- a/deps/tools/bb-install.mk +++ b/deps/tools/bb-install.mk @@ -51,7 +51,7 @@ ifneq (bsdtar,$(findstring bsdtar,$(TAR_TEST))) @# work-around a gtar bug: they do some complicated work to avoid the mkdir @# syscall, which is buggy when working with Tar.jl files so we manually do @# the mkdir calls first in a pre-pass - $(TAR) -tzf $$< | xargs -L 1 dirname | sort -u | (cd $$(build_prefix) && xargs -t mkdir -p) + $(TAR) -tzf $$< | xargs -n 1 dirname | sort -u | (cd $$(build_prefix) && xargs -t mkdir -p) endif $(UNTAR) $$< -C $$(build_prefix) echo '$$(UNINSTALL_$(strip $1))' > $$@ From 89cb6fa294a73a52258ce814c34929d6d549081d Mon Sep 17 00:00:00 2001 From: Dilum Aluthge Date: Wed, 14 Jul 2021 13:09:54 -0400 Subject: [PATCH 26/74] CI (rootfs_utils): Require that the user explicitly specify the `tag_name` (#41571) (cherry picked from commit 23dbf169f0e4b831adfd20d666bedd1f669527ca) --- .buildkite/rootfs_images/llvm-passes.jl | 7 ++++++- .buildkite/rootfs_images/rootfs_utils.jl | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.buildkite/rootfs_images/llvm-passes.jl b/.buildkite/rootfs_images/llvm-passes.jl index 3df2de49522c9..9555abe183368 100755 --- a/.buildkite/rootfs_images/llvm-passes.jl +++ b/.buildkite/rootfs_images/llvm-passes.jl @@ -4,6 +4,11 @@ ## Eventually, this image will probably be replaced with the actual builder image, ## as that will have the necessary toolchains as well, but that image is not built yet. +if length(ARGS) != 1 + throw(ArgumentError("Usage: llvm-passes.jl [tag_name]")) +end +const tag_name = convert(String, strip(ARGS[1]))::String + include("rootfs_utils.jl") # Build debian-based image with the following extra packages: @@ -26,4 +31,4 @@ packages = [ tarball_path = debootstrap("llvm-passes"; packages) # Upload it -upload_rootfs_image(tarball_path; tag_name = "v1") +upload_rootfs_image(tarball_path; tag_name) diff --git a/.buildkite/rootfs_images/rootfs_utils.jl b/.buildkite/rootfs_images/rootfs_utils.jl index 3412fbcc03f56..0079b13ae4026 100644 --- a/.buildkite/rootfs_images/rootfs_utils.jl +++ b/.buildkite/rootfs_images/rootfs_utils.jl @@ -84,7 +84,7 @@ end function upload_rootfs_image(tarball_path::String; github_repo::String="JuliaCI/rootfs-images", - tag_name::String="v1") + tag_name::String) # Upload it to `github_repo` tarball_url = "https://github.com/$(github_repo)/releases/download/$(tag_name)/$(basename(tarball_path))" @info("Uploading to $(github_repo)@$(tag_name)", tarball_url) From 61d1ca8d1bf7cccbe8c182daa62e2ec554e90eb0 Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Wed, 14 Jul 2021 15:48:03 -0400 Subject: [PATCH 27/74] increase specialization of `_totuple` (#41515) Helps #41512 (cherry picked from commit 468b1571b3676528feb1e44fd497b3bb9b55ef42) --- base/tuple.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/tuple.jl b/base/tuple.jl index dc777e7497598..421ada47c0c36 100644 --- a/base/tuple.jl +++ b/base/tuple.jl @@ -323,7 +323,7 @@ function _totuple_err(@nospecialize T) throw(ArgumentError("too few elements for tuple type $T")) end -function _totuple(T, itr, s...) +function _totuple(::Type{T}, itr, s::Vararg{Any,N}) where {T,N} @_inline_meta y = iterate(itr, s...) y === nothing && _totuple_err(T) From 687c2146302b96a40639d891a1c9f106c6d1d677 Mon Sep 17 00:00:00 2001 From: Sukera <11753998+Seelengrab@users.noreply.github.com> Date: Thu, 15 Jul 2021 12:14:27 +0200 Subject: [PATCH 28/74] REPL doc lookup assumed ASCII for the given string, fixes #41589 (#41594) (cherry picked from commit be443ac05451202fc92ca4fd8ad991c6057e0516) --- stdlib/REPL/src/docview.jl | 2 +- stdlib/REPL/test/docview.jl | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/stdlib/REPL/src/docview.jl b/stdlib/REPL/src/docview.jl index b6eb73bcd5faa..2e5fc361d8cbc 100644 --- a/stdlib/REPL/src/docview.jl +++ b/stdlib/REPL/src/docview.jl @@ -221,7 +221,7 @@ function lookup_doc(ex) str = string(ex) isdotted = startswith(str, ".") if endswith(str, "=") && Base.operator_precedence(ex) == Base.prec_assignment && ex !== :(:=) - op = str[1:end-1] + op = chop(str) eq = isdotted ? ".=" : "=" return Markdown.parse("`x $op= y` is a synonym for `x $eq x $op y`") elseif isdotted && ex !== :(..) diff --git a/stdlib/REPL/test/docview.jl b/stdlib/REPL/test/docview.jl index 1cc5037c1c806..160544eb475d2 100644 --- a/stdlib/REPL/test/docview.jl +++ b/stdlib/REPL/test/docview.jl @@ -47,3 +47,7 @@ end # shouldn't throw when there is a space in a middle of query @test (REPL.matchinds("a ", "a file.txt"); true) end + +@testset "Unicode doc lookup (#41589)" begin + @test REPL.lookup_doc(:(÷=)) isa Markdown.MD +end From 1bfd4dcb959d1dca4db5eb20f698c065afcfb55f Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Thu, 15 Jul 2021 14:31:26 -0400 Subject: [PATCH 29/74] intrinsics: optimize several atomic intrinsics (#41563) (cherry picked from commit 430e5e002b5a07b3966e694d2f681992c2123f1f) --- src/intrinsics.cpp | 195 +++++++++++++++++++++++++++++++++++---- src/julia_internal.h | 4 + src/runtime_intrinsics.c | 69 +++++++------- test/intrinsics.jl | 139 +++++++++++++++++++--------- 4 files changed, 314 insertions(+), 93 deletions(-) diff --git a/src/intrinsics.cpp b/src/intrinsics.cpp index e37ee264398e9..4096bba08d0c7 100644 --- a/src/intrinsics.cpp +++ b/src/intrinsics.cpp @@ -584,25 +584,21 @@ static jl_cgval_t emit_pointerref(jl_codectx_t &ctx, jl_cgval_t *argv) jl_value_t *ety = jl_tparam0(aty); if (jl_is_typevar(ety)) return emit_runtime_pointerref(ctx, argv); - if (!jl_is_datatype(ety)) - ety = (jl_value_t*)jl_any_type; + if (!is_valid_intrinsic_elptr(ety)) { + emit_error(ctx, "pointerref: invalid pointer type"); + return jl_cgval_t(); + } Value *idx = emit_unbox(ctx, T_size, i, (jl_value_t*)jl_long_type); Value *im1 = ctx.builder.CreateSub(idx, ConstantInt::get(T_size, 1)); if (ety == (jl_value_t*)jl_any_type) { Value *thePtr = emit_unbox(ctx, T_pprjlvalue, e, e.typ); - return mark_julia_type( - ctx, - ctx.builder.CreateAlignedLoad(ctx.builder.CreateInBoundsGEP(T_prjlvalue, thePtr, im1), Align(align_nb)), - true, - ety); + LoadInst *load = ctx.builder.CreateAlignedLoad(ctx.builder.CreateInBoundsGEP(T_prjlvalue, thePtr, im1), Align(align_nb)); + tbaa_decorate(tbaa_data, load); + return mark_julia_type(ctx, load, true, ety); } else if (!jl_isbits(ety)) { - if (!jl_is_structtype(ety) || jl_is_array_type(ety) || !jl_is_concrete_type(ety)) { - emit_error(ctx, "pointerref: invalid pointer type"); - return jl_cgval_t(); - } assert(jl_is_datatype(ety)); uint64_t size = jl_datatype_size(ety); Value *strct = emit_allocobj(ctx, size, @@ -656,8 +652,8 @@ static jl_cgval_t emit_pointerset(jl_codectx_t &ctx, jl_cgval_t *argv) return emit_runtime_pointerset(ctx, argv); if (align.constant == NULL || !jl_is_long(align.constant)) return emit_runtime_pointerset(ctx, argv); - if (!jl_is_datatype(ety)) - ety = (jl_value_t*)jl_any_type; + if (!is_valid_intrinsic_elptr(ety)) + emit_error(ctx, "pointerset: invalid pointer type"); emit_typecheck(ctx, x, ety, "pointerset"); Value *idx = emit_unbox(ctx, T_size, i, (jl_value_t*)jl_long_type); @@ -673,10 +669,6 @@ static jl_cgval_t emit_pointerset(jl_codectx_t &ctx, jl_cgval_t *argv) tbaa_decorate(tbaa_data, store); } else if (!jl_isbits(ety)) { - if (!jl_is_structtype(ety) || jl_is_array_type(ety) || !jl_is_concrete_type(ety)) { - emit_error(ctx, "pointerset: invalid pointer type"); - return jl_cgval_t(); - } thePtr = emit_unbox(ctx, T_pint8, e, e.typ); uint64_t size = jl_datatype_size(ety); im1 = ctx.builder.CreateMul(im1, ConstantInt::get(T_size, @@ -696,6 +688,170 @@ static jl_cgval_t emit_pointerset(jl_codectx_t &ctx, jl_cgval_t *argv) return e; } +static jl_cgval_t emit_atomicfence(jl_codectx_t &ctx, jl_cgval_t *argv) +{ + const jl_cgval_t &ord = argv[0]; + if (ord.constant && jl_is_symbol(ord.constant)) { + enum jl_memory_order order = jl_get_atomic_order((jl_sym_t*)ord.constant, false, false); + if (order == jl_memory_order_invalid) { + emit_atomic_error(ctx, "invalid atomic ordering"); + return jl_cgval_t(); // unreachable + } + if (order > jl_memory_order_monotonic) + ctx.builder.CreateFence(get_llvm_atomic_order(order)); + return ghostValue(jl_nothing_type); + } + return emit_runtime_call(ctx, atomic_fence, argv, 1); +} + +static jl_cgval_t emit_atomic_pointerref(jl_codectx_t &ctx, jl_cgval_t *argv) +{ + const jl_cgval_t &e = argv[0]; + const jl_cgval_t &ord = argv[1]; + jl_value_t *aty = e.typ; + if (!jl_is_cpointer_type(aty) || !ord.constant || !jl_is_symbol(ord.constant)) + return emit_runtime_call(ctx, atomic_pointerref, argv, 2); + jl_value_t *ety = jl_tparam0(aty); + if (jl_is_typevar(ety)) + return emit_runtime_call(ctx, atomic_pointerref, argv, 2); + enum jl_memory_order order = jl_get_atomic_order((jl_sym_t*)ord.constant, true, false); + if (order == jl_memory_order_invalid) { + emit_atomic_error(ctx, "invalid atomic ordering"); + return jl_cgval_t(); // unreachable + } + AtomicOrdering llvm_order = get_llvm_atomic_order(order); + + if (ety == (jl_value_t*)jl_any_type) { + Value *thePtr = emit_unbox(ctx, T_pprjlvalue, e, e.typ); + LoadInst *load = ctx.builder.CreateAlignedLoad(thePtr, Align(sizeof(jl_value_t*))); + tbaa_decorate(tbaa_data, load); + load->setOrdering(llvm_order); + return mark_julia_type(ctx, load, true, ety); + } + + if (!is_valid_intrinsic_elptr(ety)) { + emit_error(ctx, "atomic_pointerref: invalid pointer type"); + return jl_cgval_t(); + } + + size_t nb = jl_datatype_size(ety); + if ((nb & (nb - 1)) != 0 || nb > MAX_POINTERATOMIC_SIZE) { + emit_error(ctx, "atomic_pointerref: invalid pointer for atomic operation"); + return jl_cgval_t(); + } + + if (!jl_isbits(ety)) { + assert(jl_is_datatype(ety)); + uint64_t size = jl_datatype_size(ety); + Value *strct = emit_allocobj(ctx, size, + literal_pointer_val(ctx, ety)); + Value *thePtr = emit_unbox(ctx, T_pint8, e, e.typ); + Type *loadT = Type::getIntNTy(jl_LLVMContext, nb * 8); + thePtr = emit_bitcast(ctx, thePtr, loadT->getPointerTo()); + MDNode *tbaa = best_tbaa(ety); + LoadInst *load = ctx.builder.CreateAlignedLoad(loadT, thePtr, Align(nb)); + tbaa_decorate(tbaa, load); + load->setOrdering(llvm_order); + thePtr = emit_bitcast(ctx, strct, thePtr->getType()); + StoreInst *store = ctx.builder.CreateAlignedStore(load, thePtr, Align(julia_alignment(ety))); + tbaa_decorate(tbaa, store); + return mark_julia_type(ctx, strct, true, ety); + } + else { + bool isboxed; + Type *ptrty = julia_type_to_llvm(ctx, ety, &isboxed); + assert(!isboxed); + if (!type_is_ghost(ptrty)) { + Value *thePtr = emit_unbox(ctx, ptrty->getPointerTo(), e, e.typ); + return typed_load(ctx, thePtr, nullptr, ety, tbaa_data, nullptr, isboxed, llvm_order, true, nb); + } + else { + if (order > jl_memory_order_monotonic) + ctx.builder.CreateFence(llvm_order); + return ghostValue(ety); + } + } +} + +// e[i] = x (set) +// e[i] <= x (swap) +// e[i] y => x (replace) +static jl_cgval_t emit_atomic_pointerset(jl_codectx_t &ctx, intrinsic f, const jl_cgval_t *argv, int nargs) +{ + bool issetfield = f == atomic_pointerset; + bool isreplacefield = f == atomic_pointerreplace; + const jl_cgval_t undefval; + const jl_cgval_t &e = argv[0]; + const jl_cgval_t &x = isreplacefield ? argv[2] : argv[1]; + const jl_cgval_t &y = isreplacefield ? argv[1] : undefval; + const jl_cgval_t &ord = isreplacefield ? argv[3] : argv[2]; + const jl_cgval_t &failord = isreplacefield ? argv[4] : undefval; + + jl_value_t *aty = e.typ; + if (!jl_is_cpointer_type(aty) || !ord.constant || !jl_is_symbol(ord.constant)) + return emit_runtime_call(ctx, f, argv, nargs); + if (isreplacefield) { + if (!failord.constant || !jl_is_symbol(failord.constant)) + return emit_runtime_call(ctx, f, argv, nargs); + } + jl_value_t *ety = jl_tparam0(aty); + if (jl_is_typevar(ety)) + return emit_runtime_call(ctx, f, argv, nargs); + enum jl_memory_order order = jl_get_atomic_order((jl_sym_t*)ord.constant, !issetfield, true); + enum jl_memory_order failorder = isreplacefield ? jl_get_atomic_order((jl_sym_t*)failord.constant, true, false) : order; + if (order == jl_memory_order_invalid || failorder == jl_memory_order_invalid || failorder > order) { + emit_atomic_error(ctx, "invalid atomic ordering"); + return jl_cgval_t(); // unreachable + } + AtomicOrdering llvm_order = get_llvm_atomic_order(order); + AtomicOrdering llvm_failorder = get_llvm_atomic_order(failorder); + + if (ety == (jl_value_t*)jl_any_type) { + // unsafe_store to Ptr{Any} is allowed to implicitly drop GC roots. + // n.b.: the expected value (y) must be rooted, but not the others + Value *thePtr = emit_unbox(ctx, T_pprjlvalue, e, e.typ); + bool isboxed = true; + jl_cgval_t ret = typed_store(ctx, thePtr, nullptr, x, y, ety, tbaa_data, nullptr, nullptr, isboxed, + llvm_order, llvm_failorder, sizeof(jl_value_t*), false, issetfield, isreplacefield, false); + if (issetfield) + ret = e; + return ret; + } + + if (!is_valid_intrinsic_elptr(ety)) { + std::string msg(StringRef(jl_intrinsic_name((int)f))); + msg += ": invalid pointer type"; + emit_error(ctx, msg); + return jl_cgval_t(); + } + emit_typecheck(ctx, x, ety, std::string(jl_intrinsic_name((int)f))); + + size_t nb = jl_datatype_size(ety); + if ((nb & (nb - 1)) != 0 || nb > MAX_POINTERATOMIC_SIZE) { + std::string msg(StringRef(jl_intrinsic_name((int)f))); + msg += ": invalid pointer for atomic operation"; + emit_error(ctx, msg); + return jl_cgval_t(); + } + + if (!jl_isbits(ety)) { + //Value *thePtr = emit_unbox(ctx, T_pint8, e, e.typ); + //uint64_t size = jl_datatype_size(ety); + return emit_runtime_call(ctx, f, argv, nargs); // TODO: optimizations + } + else { + bool isboxed; + Type *ptrty = julia_type_to_llvm(ctx, ety, &isboxed); + assert(!isboxed); + Value *thePtr = emit_unbox(ctx, ptrty->getPointerTo(), e, e.typ); + jl_cgval_t ret = typed_store(ctx, thePtr, nullptr, x, y, ety, tbaa_data, nullptr, nullptr, isboxed, + llvm_order, llvm_failorder, nb, false, issetfield, isreplacefield, false); + if (issetfield) + ret = e; + return ret; + } +} + static Value *emit_checked_srem_int(jl_codectx_t &ctx, Value *x, Value *den) { Type *t = den->getType(); @@ -924,11 +1080,14 @@ static jl_cgval_t emit_intrinsic(jl_codectx_t &ctx, intrinsic f, jl_value_t **ar case pointerset: return emit_pointerset(ctx, argv); case atomic_fence: + return emit_atomicfence(ctx, argv); case atomic_pointerref: + return emit_atomic_pointerref(ctx, argv); case atomic_pointerset: case atomic_pointerswap: - case atomic_pointermodify: case atomic_pointerreplace: + return emit_atomic_pointerset(ctx, f, argv, nargs); + case atomic_pointermodify: return emit_runtime_call(ctx, f, argv, nargs); case bitcast: return generic_bitcast(ctx, argv); diff --git a/src/julia_internal.h b/src/julia_internal.h index 11eb24330c638..f4d63cc27cf78 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -1110,6 +1110,10 @@ extern JL_DLLEXPORT jl_value_t *jl_segv_exception; JL_DLLEXPORT const char *jl_intrinsic_name(int f) JL_NOTSAFEPOINT; unsigned jl_intrinsic_nargs(int f) JL_NOTSAFEPOINT; +STATIC_INLINE int is_valid_intrinsic_elptr(jl_value_t *ety) +{ + return ety == (jl_value_t*)jl_any_type || (jl_is_concrete_type(ety) && !jl_is_layout_opaque(((jl_datatype_t*)ety)->layout)); +} JL_DLLEXPORT jl_value_t *jl_bitcast(jl_value_t *ty, jl_value_t *v); JL_DLLEXPORT jl_value_t *jl_pointerref(jl_value_t *p, jl_value_t *i, jl_value_t *align); JL_DLLEXPORT jl_value_t *jl_pointerset(jl_value_t *p, jl_value_t *x, jl_value_t *align, jl_value_t *i); diff --git a/src/runtime_intrinsics.c b/src/runtime_intrinsics.c index c7c31bb98a86d..7cb58bc230294 100644 --- a/src/runtime_intrinsics.c +++ b/src/runtime_intrinsics.c @@ -43,7 +43,7 @@ JL_DLLEXPORT jl_value_t *jl_pointerref(jl_value_t *p, jl_value_t *i, jl_value_t return *pp; } else { - if (!jl_is_datatype(ety)) + if (!is_valid_intrinsic_elptr(ety)) jl_error("pointerref: invalid pointer"); size_t nb = LLT_ALIGN(jl_datatype_size(ety), jl_datatype_align(ety)); char *pp = (char*)jl_unbox_long(p) + (jl_unbox_long(i)-1)*nb; @@ -56,14 +56,14 @@ JL_DLLEXPORT jl_value_t *jl_pointerset(jl_value_t *p, jl_value_t *x, jl_value_t { JL_TYPECHK(pointerset, pointer, p); JL_TYPECHK(pointerset, long, i); - JL_TYPECHK(pointerref, long, align); + JL_TYPECHK(pointerset, long, align); jl_value_t *ety = jl_tparam0(jl_typeof(p)); if (ety == (jl_value_t*)jl_any_type) { jl_value_t **pp = (jl_value_t**)(jl_unbox_long(p) + (jl_unbox_long(i)-1)*sizeof(void*)); *pp = x; } else { - if (!jl_is_datatype(ety)) + if (!is_valid_intrinsic_elptr(ety)) jl_error("pointerset: invalid pointer"); if (jl_typeof(x) != ety) jl_type_error("pointerset", ety, x); @@ -77,8 +77,8 @@ JL_DLLEXPORT jl_value_t *jl_pointerset(jl_value_t *p, jl_value_t *x, jl_value_t JL_DLLEXPORT jl_value_t *jl_atomic_pointerref(jl_value_t *p, jl_value_t *order) { - JL_TYPECHK(pointerref, pointer, p); - JL_TYPECHK(pointerref, symbol, order) + JL_TYPECHK(atomic_pointerref, pointer, p); + JL_TYPECHK(atomic_pointerref, symbol, order) (void)jl_get_atomic_order_checked((jl_sym_t*)order, 1, 0); jl_value_t *ety = jl_tparam0(jl_typeof(p)); char *pp = (char*)jl_unbox_long(p); @@ -86,19 +86,19 @@ JL_DLLEXPORT jl_value_t *jl_atomic_pointerref(jl_value_t *p, jl_value_t *order) return jl_atomic_load((jl_value_t**)pp); } else { - if (!jl_is_datatype(ety)) - jl_error("pointerref: invalid pointer"); + if (!is_valid_intrinsic_elptr(ety)) + jl_error("atomic_pointerref: invalid pointer"); size_t nb = jl_datatype_size(ety); if ((nb & (nb - 1)) != 0 || nb > MAX_POINTERATOMIC_SIZE) - jl_error("pointerref: invalid pointer for atomic operation"); + jl_error("atomic_pointerref: invalid pointer for atomic operation"); return jl_atomic_new_bits(ety, pp); } } JL_DLLEXPORT jl_value_t *jl_atomic_pointerset(jl_value_t *p, jl_value_t *x, jl_value_t *order) { - JL_TYPECHK(pointerset, pointer, p); - JL_TYPECHK(pointerset, symbol, order); + JL_TYPECHK(atomic_pointerset, pointer, p); + JL_TYPECHK(atomic_pointerset, symbol, order); (void)jl_get_atomic_order_checked((jl_sym_t*)order, 0, 1); jl_value_t *ety = jl_tparam0(jl_typeof(p)); char *pp = (char*)jl_unbox_long(p); @@ -106,13 +106,13 @@ JL_DLLEXPORT jl_value_t *jl_atomic_pointerset(jl_value_t *p, jl_value_t *x, jl_v jl_atomic_store((jl_value_t**)pp, x); } else { - if (!jl_is_datatype(ety)) - jl_error("pointerset: invalid pointer"); + if (!is_valid_intrinsic_elptr(ety)) + jl_error("atomic_pointerset: invalid pointer"); if (jl_typeof(x) != ety) - jl_type_error("pointerset", ety, x); + jl_type_error("atomic_pointerset", ety, x); size_t nb = jl_datatype_size(ety); if ((nb & (nb - 1)) != 0 || nb > MAX_POINTERATOMIC_SIZE) - jl_error("pointerset: invalid pointer for atomic operation"); + jl_error("atomic_pointerset: invalid pointer for atomic operation"); jl_atomic_store_bits(pp, x, nb); } return p; @@ -120,8 +120,8 @@ JL_DLLEXPORT jl_value_t *jl_atomic_pointerset(jl_value_t *p, jl_value_t *x, jl_v JL_DLLEXPORT jl_value_t *jl_atomic_pointerswap(jl_value_t *p, jl_value_t *x, jl_value_t *order) { - JL_TYPECHK(pointerswap, pointer, p); - JL_TYPECHK(pointerswap, symbol, order); + JL_TYPECHK(atomic_pointerswap, pointer, p); + JL_TYPECHK(atomic_pointerswap, symbol, order); (void)jl_get_atomic_order_checked((jl_sym_t*)order, 1, 1); jl_value_t *ety = jl_tparam0(jl_typeof(p)); jl_value_t *y; @@ -130,13 +130,13 @@ JL_DLLEXPORT jl_value_t *jl_atomic_pointerswap(jl_value_t *p, jl_value_t *x, jl_ y = jl_atomic_exchange((jl_value_t**)pp, x); } else { - if (!jl_is_datatype(ety)) - jl_error("pointerswap: invalid pointer"); + if (!is_valid_intrinsic_elptr(ety)) + jl_error("atomic_pointerswap: invalid pointer"); if (jl_typeof(x) != ety) - jl_type_error("pointerswap", ety, x); + jl_type_error("atomic_pointerswap", ety, x); size_t nb = jl_datatype_size(ety); if ((nb & (nb - 1)) != 0 || nb > MAX_POINTERATOMIC_SIZE) - jl_error("pointerswap: invalid pointer for atomic operation"); + jl_error("atomic_pointerswap: invalid pointer for atomic operation"); y = jl_atomic_swap_bits(ety, pp, x, nb); } return y; @@ -163,8 +163,10 @@ JL_DLLEXPORT jl_value_t *jl_atomic_pointermodify(jl_value_t *p, jl_value_t *f, j break; } else { + //if (!is_valid_intrinsic_elptr(ety)) // handled by jl_atomic_pointerref earlier + // jl_error("atomic_pointermodify: invalid pointer"); if (jl_typeof(y) != ety) - jl_type_error("pointermodify", ety, y); + jl_type_error("atomic_pointermodify", ety, y); size_t nb = jl_datatype_size(ety); if (jl_atomic_bool_cmpswap_bits(pp, expected, y, nb)) break; @@ -181,13 +183,13 @@ JL_DLLEXPORT jl_value_t *jl_atomic_pointermodify(jl_value_t *p, jl_value_t *f, j JL_DLLEXPORT jl_value_t *jl_atomic_pointerreplace(jl_value_t *p, jl_value_t *expected, jl_value_t *x, jl_value_t *success_order_sym, jl_value_t *failure_order_sym) { - JL_TYPECHK(pointerreplace, pointer, p); - JL_TYPECHK(pointerreplace, symbol, success_order_sym); - JL_TYPECHK(pointerreplace, symbol, failure_order_sym); + JL_TYPECHK(atomic_pointerreplace, pointer, p); + JL_TYPECHK(atomic_pointerreplace, symbol, success_order_sym); + JL_TYPECHK(atomic_pointerreplace, symbol, failure_order_sym); enum jl_memory_order success_order = jl_get_atomic_order_checked((jl_sym_t*)success_order_sym, 1, 1); enum jl_memory_order failure_order = jl_get_atomic_order_checked((jl_sym_t*)failure_order_sym, 1, 0); if (failure_order > success_order) - jl_atomic_error("pointerreplace: invalid atomic ordering"); + jl_atomic_error("atomic_pointerreplace: invalid atomic ordering"); // TODO: filter other invalid orderings jl_value_t *ety = jl_tparam0(jl_typeof(p)); char *pp = (char*)jl_unbox_long(p); @@ -207,22 +209,23 @@ JL_DLLEXPORT jl_value_t *jl_atomic_pointerreplace(jl_value_t *p, jl_value_t *exp return result[0]; } else { - if (!jl_is_datatype(ety)) - jl_error("pointerreplace: invalid pointer"); + if (!is_valid_intrinsic_elptr(ety)) + jl_error("atomic_pointerreplace: invalid pointer"); if (jl_typeof(x) != ety) - jl_type_error("pointerreplace", ety, x); + jl_type_error("atomic_pointerreplace", ety, x); size_t nb = jl_datatype_size(ety); if ((nb & (nb - 1)) != 0 || nb > MAX_POINTERATOMIC_SIZE) - jl_error("pointerreplace: invalid pointer for atomic operation"); + jl_error("atomic_pointerreplace: invalid pointer for atomic operation"); return jl_atomic_cmpswap_bits((jl_datatype_t*)ety, pp, expected, x, nb); } } -JL_DLLEXPORT jl_value_t *jl_atomic_fence(jl_value_t *order) +JL_DLLEXPORT jl_value_t *jl_atomic_fence(jl_value_t *order_sym) { - JL_TYPECHK(fence, symbol, order); - (void)jl_get_atomic_order_checked((jl_sym_t*)order, 0, 0); - jl_fence(); + JL_TYPECHK(fence, symbol, order_sym); + enum jl_memory_order order = jl_get_atomic_order_checked((jl_sym_t*)order_sym, 0, 0); + if (order > jl_memory_order_monotonic) + jl_fence(); return jl_nothing; } diff --git a/test/intrinsics.jl b/test/intrinsics.jl index c1d3019f8db35..7fa8ecb0ebe27 100644 --- a/test/intrinsics.jl +++ b/test/intrinsics.jl @@ -171,51 +171,106 @@ primitive type Int512 <: Signed 512 end Int512(i::Int) = Core.Intrinsics.sext_int(Int512, i) function add(i::T, j)::T where {T}; return i + j; end swap(i, j) = j + for TT in (Int8, Int16, Int32, Int64, Int128, Int256, Int512, Complex{Int32}, Complex{Int512}, Any) - T(x) = convert(TT, x) r = Ref{TT}(10) - p = Base.unsafe_convert(Ptr{eltype(r)}, r) GC.@preserve r begin - S = UInt32 - if TT !== Any - @test_throws TypeError Core.Intrinsics.atomic_pointerset(p, S(1), :sequentially_consistent) - @test_throws TypeError Core.Intrinsics.atomic_pointerswap(p, S(100), :sequentially_consistent) - @test_throws TypeError Core.Intrinsics.atomic_pointerreplace(p, T(100), S(2), :sequentially_consistent, :sequentially_consistent) - end - @test Core.Intrinsics.pointerref(p, 1, 1) === T(10) === r[] - if sizeof(r) > 8 - @test_throws ErrorException("pointerref: invalid pointer for atomic operation") Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) - @test_throws ErrorException("pointerset: invalid pointer for atomic operation") Core.Intrinsics.atomic_pointerset(p, T(1), :sequentially_consistent) - @test_throws ErrorException("pointerswap: invalid pointer for atomic operation") Core.Intrinsics.atomic_pointerswap(p, T(100), :sequentially_consistent) - @test_throws ErrorException("pointerref: invalid pointer for atomic operation") Core.Intrinsics.atomic_pointermodify(p, add, T(1), :sequentially_consistent) - @test_throws ErrorException("pointerref: invalid pointer for atomic operation") Core.Intrinsics.atomic_pointermodify(p, swap, S(1), :sequentially_consistent) - @test_throws ErrorException("pointerreplace: invalid pointer for atomic operation") Core.Intrinsics.atomic_pointerreplace(p, T(100), T(2), :sequentially_consistent, :sequentially_consistent) - @test_throws ErrorException("pointerreplace: invalid pointer for atomic operation") Core.Intrinsics.atomic_pointerreplace(p, S(100), T(2), :sequentially_consistent, :sequentially_consistent) + (function (::Type{TT}) where TT + p = Base.unsafe_convert(Ptr{TT}, r) + T(x) = convert(TT, x) + S = UInt32 + if TT !== Any + @test_throws TypeError Core.Intrinsics.atomic_pointerset(p, S(1), :sequentially_consistent) + @test_throws TypeError Core.Intrinsics.atomic_pointerswap(p, S(100), :sequentially_consistent) + @test_throws TypeError Core.Intrinsics.atomic_pointerreplace(p, T(100), S(2), :sequentially_consistent, :sequentially_consistent) + end @test Core.Intrinsics.pointerref(p, 1, 1) === T(10) === r[] - else - TT !== Any && @test_throws TypeError Core.Intrinsics.atomic_pointermodify(p, swap, S(1), :sequentially_consistent) - @test Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) === T(10) - @test Core.Intrinsics.atomic_pointerset(p, T(1), :sequentially_consistent) === p - @test Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) === T(1) - @test Core.Intrinsics.atomic_pointerreplace(p, T(1), T(100), :sequentially_consistent, :sequentially_consistent) === (T(1), true) - @test Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) === T(100) - @test Core.Intrinsics.atomic_pointerreplace(p, T(1), T(1), :sequentially_consistent, :sequentially_consistent) === (T(100), false) - @test Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) === T(100) - @test Core.Intrinsics.atomic_pointermodify(p, add, T(1), :sequentially_consistent) === (T(100), T(101)) - @test Core.Intrinsics.atomic_pointermodify(p, add, T(1), :sequentially_consistent) === (T(101), T(102)) - @test Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) === T(102) - @test Core.Intrinsics.atomic_pointerswap(p, T(103), :sequentially_consistent) === T(102) - @test Core.Intrinsics.atomic_pointerreplace(p, S(100), T(2), :sequentially_consistent, :sequentially_consistent) === (T(103), false) - @test Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) === T(103) - end - if TT === Any - @test Core.Intrinsics.atomic_pointermodify(p, swap, S(103), :sequentially_consistent) === (T(103), S(103)) - @test Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) === S(103) - @test Core.Intrinsics.atomic_pointerset(p, S(1), :sequentially_consistent) === p - @test Core.Intrinsics.atomic_pointerswap(p, S(100), :sequentially_consistent) === S(1) - @test Core.Intrinsics.atomic_pointerreplace(p, T(100), S(2), :sequentially_consistent, :sequentially_consistent) === (S(100), false) - @test Core.Intrinsics.atomic_pointerreplace(p, S(100), T(2), :sequentially_consistent, :sequentially_consistent) === (S(100), true) - @test Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) === T(2) - end + if sizeof(r) > 8 + @test_throws ErrorException("atomic_pointerref: invalid pointer for atomic operation") Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) + @test_throws ErrorException("atomic_pointerset: invalid pointer for atomic operation") Core.Intrinsics.atomic_pointerset(p, T(1), :sequentially_consistent) + @test_throws ErrorException("atomic_pointerswap: invalid pointer for atomic operation") Core.Intrinsics.atomic_pointerswap(p, T(100), :sequentially_consistent) + @test_throws ErrorException("atomic_pointerref: invalid pointer for atomic operation") Core.Intrinsics.atomic_pointermodify(p, add, T(1), :sequentially_consistent) + @test_throws ErrorException("atomic_pointerref: invalid pointer for atomic operation") Core.Intrinsics.atomic_pointermodify(p, swap, S(1), :sequentially_consistent) + @test_throws ErrorException("atomic_pointerreplace: invalid pointer for atomic operation") Core.Intrinsics.atomic_pointerreplace(p, T(100), T(2), :sequentially_consistent, :sequentially_consistent) + @test_throws ErrorException("atomic_pointerreplace: invalid pointer for atomic operation") Core.Intrinsics.atomic_pointerreplace(p, S(100), T(2), :sequentially_consistent, :sequentially_consistent) + @test Core.Intrinsics.pointerref(p, 1, 1) === T(10) === r[] + else + TT !== Any && @test_throws TypeError Core.Intrinsics.atomic_pointermodify(p, swap, S(1), :sequentially_consistent) + @test Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) === T(10) + @test Core.Intrinsics.atomic_pointerset(p, T(1), :sequentially_consistent) === p + @test Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) === T(1) + @test Core.Intrinsics.atomic_pointerreplace(p, T(1), T(100), :sequentially_consistent, :sequentially_consistent) === (T(1), true) + @test Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) === T(100) + @test Core.Intrinsics.atomic_pointerreplace(p, T(1), T(1), :sequentially_consistent, :sequentially_consistent) === (T(100), false) + @test Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) === T(100) + @test Core.Intrinsics.atomic_pointermodify(p, add, T(1), :sequentially_consistent) === (T(100), T(101)) + @test Core.Intrinsics.atomic_pointermodify(p, add, T(1), :sequentially_consistent) === (T(101), T(102)) + @test Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) === T(102) + @test Core.Intrinsics.atomic_pointerswap(p, T(103), :sequentially_consistent) === T(102) + @test Core.Intrinsics.atomic_pointerreplace(p, S(100), T(2), :sequentially_consistent, :sequentially_consistent) === (T(103), false) + @test Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) === T(103) + end + if TT === Any + @test Core.Intrinsics.atomic_pointermodify(p, swap, S(103), :sequentially_consistent) === (T(103), S(103)) + @test Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) === S(103) + @test Core.Intrinsics.atomic_pointerset(p, S(1), :sequentially_consistent) === p + @test Core.Intrinsics.atomic_pointerswap(p, S(100), :sequentially_consistent) === S(1) + @test Core.Intrinsics.atomic_pointerreplace(p, T(100), S(2), :sequentially_consistent, :sequentially_consistent) === (S(100), false) + @test Core.Intrinsics.atomic_pointerreplace(p, S(100), T(2), :sequentially_consistent, :sequentially_consistent) === (S(100), true) + @test Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) === T(2) + end + end)(TT,) end end + +mutable struct IntWrap <: Signed + x::Int +end +Base.:(+)(a::IntWrap, b::Int) = IntWrap(a.x + b) +Base.:(+)(a::IntWrap, b::IntWrap) = IntWrap(a.x + b.x) +Base.show(io::IO, a::IntWrap) = print(io, "IntWrap(", a.x, ")") +(function() + TT = IntWrap + T(x) = convert(TT, x) + r = Ref{TT}(10) + p = Base.unsafe_convert(Ptr{TT}, r) + GC.@preserve r begin + S = UInt32 + @test_throws TypeError Core.Intrinsics.atomic_pointerset(p, S(1), :sequentially_consistent) + @test_throws TypeError Core.Intrinsics.atomic_pointerswap(p, S(100), :sequentially_consistent) + @test_throws TypeError Core.Intrinsics.atomic_pointerreplace(p, T(100), S(2), :sequentially_consistent, :sequentially_consistent) + r2 = Core.Intrinsics.pointerref(p, 1, 1) + @test r2 isa IntWrap && r2.x === 10 === r[].x && r2 !== r[] + @test_throws TypeError Core.Intrinsics.atomic_pointermodify(p, swap, S(1), :sequentially_consistent) + r2 = Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) + @test r2 isa IntWrap && r2.x === 10 === r[].x && r2 !== r[] + @test Core.Intrinsics.atomic_pointerset(p, T(1), :sequentially_consistent) === p + r2 = Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) + @test r2 isa IntWrap && r2.x === 1 === r[].x && r2 !== r[] + r2, succ = Core.Intrinsics.atomic_pointerreplace(p, T(1), T(100), :sequentially_consistent, :sequentially_consistent) + @test r2 isa IntWrap && r2.x === 1 && r[].x === 100 && r2 !== r[] + @test succ + r2 = Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) + @test r2 isa IntWrap && r2.x === 100 === r[].x && r2 !== r[] + r2, succ = Core.Intrinsics.atomic_pointerreplace(p, T(1), T(1), :sequentially_consistent, :sequentially_consistent) + @test r2 isa IntWrap && r2.x === 100 === r[].x && r2 !== r[] + @test !succ + r2 = Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) + @test r2 isa IntWrap && r2.x === 100 === r[].x && r2 !== r[] + r2, r3 = Core.Intrinsics.atomic_pointermodify(p, add, T(1), :sequentially_consistent) + @test r2 isa IntWrap && r2.x === 100 !== r[].x && r2 !== r[] + @test r3 isa IntWrap && r3.x === 101 === r[].x && r3 !== r[] + r2, r3 = Core.Intrinsics.atomic_pointermodify(p, add, T(1), :sequentially_consistent) + @test r2 isa IntWrap && r2.x === 101 !== r[].x && r2 !== r[] + @test r3 isa IntWrap && r3.x === 102 === r[].x && r3 !== r[] + r2 = Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) + @test r2 isa IntWrap && r2.x === 102 === r[].x && r2 !== r[] + r2 = Core.Intrinsics.atomic_pointerswap(p, T(103), :sequentially_consistent) + @test r2 isa IntWrap && r2.x === 102 !== r[].x && r[].x == 103 && r2 !== r[] + r2, succ = Core.Intrinsics.atomic_pointerreplace(p, S(100), T(2), :sequentially_consistent, :sequentially_consistent) + @test r2 isa IntWrap && r2.x === 103 === r[].x && r2 !== r[] + @test !succ + r2 = Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) + @test r2 isa IntWrap && r2.x === 103 === r[].x && r2 !== r[] + end +end)() From 99d27f6fc40abbb145b5e9832c277c17ae96c3e3 Mon Sep 17 00:00:00 2001 From: Dilum Aluthge Date: Thu, 15 Jul 2021 18:55:37 -0400 Subject: [PATCH 30/74] CI (rootfs images): when uploading a tarball, don't allow it to override an existing tarball (unless the user provides the `--force-overwrite` command-line flag) (#41591) Co-authored-by: Elliot Saba Co-authored-by: Elliot Saba (cherry picked from commit 3ac7c383a1d5825866664939e6e2de694c55d19d) --- .buildkite/rootfs_images/llvm-passes.jl | 9 +++---- .buildkite/rootfs_images/rootfs_utils.jl | 31 ++++++++++++++++++++++-- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/.buildkite/rootfs_images/llvm-passes.jl b/.buildkite/rootfs_images/llvm-passes.jl index 9555abe183368..bc6d57eb2f87e 100755 --- a/.buildkite/rootfs_images/llvm-passes.jl +++ b/.buildkite/rootfs_images/llvm-passes.jl @@ -4,13 +4,10 @@ ## Eventually, this image will probably be replaced with the actual builder image, ## as that will have the necessary toolchains as well, but that image is not built yet. -if length(ARGS) != 1 - throw(ArgumentError("Usage: llvm-passes.jl [tag_name]")) -end -const tag_name = convert(String, strip(ARGS[1]))::String - include("rootfs_utils.jl") +const tag_name, force_overwrite = get_arguments(ARGS, @__FILE__) + # Build debian-based image with the following extra packages: packages = [ "bash", @@ -31,4 +28,4 @@ packages = [ tarball_path = debootstrap("llvm-passes"; packages) # Upload it -upload_rootfs_image(tarball_path; tag_name) +upload_rootfs_image(tarball_path; tag_name, force_overwrite) diff --git a/.buildkite/rootfs_images/rootfs_utils.jl b/.buildkite/rootfs_images/rootfs_utils.jl index 0079b13ae4026..3d31747e0e6f8 100644 --- a/.buildkite/rootfs_images/rootfs_utils.jl +++ b/.buildkite/rootfs_images/rootfs_utils.jl @@ -84,10 +84,37 @@ end function upload_rootfs_image(tarball_path::String; github_repo::String="JuliaCI/rootfs-images", - tag_name::String) + tag_name::String, + force_overwrite::Bool) # Upload it to `github_repo` tarball_url = "https://github.com/$(github_repo)/releases/download/$(tag_name)/$(basename(tarball_path))" @info("Uploading to $(github_repo)@$(tag_name)", tarball_url) - run(`$(ghr_jll.ghr()) -u $(dirname(github_repo)) -r $(basename(github_repo)) -replace $(tag_name) $(tarball_path)`) + replace_flag = force_overwrite ? "-replace" : "" + run(`$(ghr_jll.ghr()) -u $(dirname(github_repo)) -r $(basename(github_repo)) $(replace_flag) $(tag_name) $(tarball_path)`) return tarball_url end + +# process command-line arguments + +function get_arguments(args::AbstractVector, script_file::AbstractString) + usage = "Usage: $(basename(script_file)) [--force-overwrite]" + length(args) < 1 && throw(ArgumentError(usage)) + length(args) > 2 && throw(ArgumentError(usage)) + tag_name = get_tag_name(args; usage) + force_overwrite = get_force_overwrite(args; usage) + return (; tag_name, force_overwrite) +end + +function get_tag_name(args::AbstractVector; usage::AbstractString) + tag_name = convert(String, strip(args[1]))::String + isempty(tag_name) && throw(ArgumentError(usage)) + startswith(tag_name, "--") && throw(ArgumentError(usage)) + return tag_name +end + +function get_force_overwrite(args::AbstractVector; usage::AbstractString) + force_overwrite_string = strip(get(args, 2, "")) + force_overwrite_string == "" && return false + force_overwrite_string == "--force-overwrite" && return true + throw(ArgumentError(usage)) +end From 735724abbda2fd5c40b211694a8e21e6a826b212 Mon Sep 17 00:00:00 2001 From: Dilum Aluthge Date: Fri, 16 Jul 2021 16:19:50 -0400 Subject: [PATCH 31/74] CI (rootfs images): fix a bug in the `upload_rootfs_image` function (#41610) (cherry picked from commit e1aeb8a95ede8212ea09bdb49bdd805f66dfb9d5) --- .buildkite/rootfs_images/rootfs_utils.jl | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.buildkite/rootfs_images/rootfs_utils.jl b/.buildkite/rootfs_images/rootfs_utils.jl index 3d31747e0e6f8..82baeec7a0933 100644 --- a/.buildkite/rootfs_images/rootfs_utils.jl +++ b/.buildkite/rootfs_images/rootfs_utils.jl @@ -89,8 +89,11 @@ function upload_rootfs_image(tarball_path::String; # Upload it to `github_repo` tarball_url = "https://github.com/$(github_repo)/releases/download/$(tag_name)/$(basename(tarball_path))" @info("Uploading to $(github_repo)@$(tag_name)", tarball_url) - replace_flag = force_overwrite ? "-replace" : "" - run(`$(ghr_jll.ghr()) -u $(dirname(github_repo)) -r $(basename(github_repo)) $(replace_flag) $(tag_name) $(tarball_path)`) + cmd = ghr_jll.ghr() + append!(cmd.exec, ["-u", dirname(github_repo), "-r", basename(github_repo)]) + force_overwrite && push!(cmd.exec, "-replace") + append!(cmd.exec, [tag_name, tarball_path]) + run(cmd) return tarball_url end From a2b980de3981be0703730c8d69e71c590cad05f9 Mon Sep 17 00:00:00 2001 From: Elliot Saba Date: Wed, 7 Jul 2021 14:43:45 -0700 Subject: [PATCH 32/74] Add signed pipeline test back (cherry picked from commit 480ff81e78b2d7b139ec34f0f2d70cfdc51895d2) (cherry picked from commit dad0f150958899f1f0d632a1974c6af897389c46) --- .buildkite/0_webui.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.buildkite/0_webui.yml b/.buildkite/0_webui.yml index aed6a5e59d9c3..d5ba4e0ea7cf9 100644 --- a/.buildkite/0_webui.yml +++ b/.buildkite/0_webui.yml @@ -19,6 +19,6 @@ steps: # Our signed pipelines must have a `signature` or `signature_file` parameter that # verifies the treehash of the pipeline itself and the inputs listed in `inputs` - #signed_pipelines: - # - pipeline: .buildkite/signed_pipeline_test.yml - # signature: "U2FsdGVkX18aZgryp6AJTArgD2uOnVWyFFGVOP5qsY4WbGQ/LVAcYiMEp9cweV+2iht+vmEF949CuuGTeQPA1fKlhPwkG3nZ688752DUB6en9oM2nuL31NoDKWHhpygZ" + signed_pipelines: + - pipeline: .buildkite/signed_pipeline_test.yml + signature: "U2FsdGVkX18aZgryp6AJTArgD2uOnVWyFFGVOP5qsY4WbGQ/LVAcYiMEp9cweV+2iht+vmEF949CuuGTeQPA1fKlhPwkG3nZ688752DUB6en9oM2nuL31NoDKWHhpygZ" From 17f5c9d5660766418b628185913090e62e4b2ec3 Mon Sep 17 00:00:00 2001 From: Dilum Aluthge Date: Thu, 8 Jul 2021 11:44:44 -0400 Subject: [PATCH 33/74] CI (code coverage): run some tests in serial (#41507) (cherry picked from commit 9564bfbd6cc0254bb6ee900e09034e7291ca7e19) --- .buildkite/0_webui.yml | 2 +- .buildkite/coverage-linux64/0_webui.yml | 2 +- .buildkite/coverage-linux64/pipeline.yml | 15 ++++++++++++--- .../{run_tests_base.jl => run_tests_parallel.jl} | 0 .buildkite/coverage-linux64/run_tests_serial.jl | 16 ++++++++++++++++ 5 files changed, 30 insertions(+), 5 deletions(-) rename .buildkite/coverage-linux64/{run_tests_base.jl => run_tests_parallel.jl} (100%) create mode 100644 .buildkite/coverage-linux64/run_tests_serial.jl diff --git a/.buildkite/0_webui.yml b/.buildkite/0_webui.yml index d5ba4e0ea7cf9..440d2d443ce7e 100644 --- a/.buildkite/0_webui.yml +++ b/.buildkite/0_webui.yml @@ -21,4 +21,4 @@ steps: # verifies the treehash of the pipeline itself and the inputs listed in `inputs` signed_pipelines: - pipeline: .buildkite/signed_pipeline_test.yml - signature: "U2FsdGVkX18aZgryp6AJTArgD2uOnVWyFFGVOP5qsY4WbGQ/LVAcYiMEp9cweV+2iht+vmEF949CuuGTeQPA1fKlhPwkG3nZ688752DUB6en9oM2nuL31NoDKWHhpygZ" + signature: "U2FsdGVkX18ZrMlORSIi0TvW99eZ3JyUEhntMyXjrOSJ9jAtUohgHc8+dMnWUc6qWjYt8k63wfPrth33SGWDiF814Bm1W5Zk3+R6HgVu6UCrQEI5sLm+SJPbrvET+Jkn" diff --git a/.buildkite/coverage-linux64/0_webui.yml b/.buildkite/coverage-linux64/0_webui.yml index 6dafcd86f6bcd..b0df8ec41de68 100644 --- a/.buildkite/coverage-linux64/0_webui.yml +++ b/.buildkite/coverage-linux64/0_webui.yml @@ -13,4 +13,4 @@ steps: # verifies the treehash of the pipeline itself and the inputs listed in `inputs` signed_pipelines: - pipeline: .buildkite/coverage-linux64/pipeline.yml - signature: "U2FsdGVkX18eQWpd3hMYLO5Kd+6K+oBoLk1I6J3qIw7lc6g5/jaeWyq/wralosZCfTzyjS4NstNKFvhQf3KDPEBVElipNvTxoWOjVLRVOrfBqqvTkQN4xVosY/r026Gy" + signature: U2FsdGVkX190BiaBGCTT6GNBDe5cHX3ZAP0IXbBfOWo7ys+1IuD5ymf4ImJbRIeE8NQac+iqud+bqCPHjii6DKmqzX+Jz6vax1NY3AxROhYlO5spUClvKr1wdngUCQON diff --git a/.buildkite/coverage-linux64/pipeline.yml b/.buildkite/coverage-linux64/pipeline.yml index 078b00254c4f9..218212d24ac2a 100644 --- a/.buildkite/coverage-linux64/pipeline.yml +++ b/.buildkite/coverage-linux64/pipeline.yml @@ -31,9 +31,18 @@ steps: # this is necessary to make sure that the LibGit2 tests passes git config --global init.defaultBranch master - echo "--- Run Julia tests with code coverage enabled" - # Run the actual tests - ./julia --code-coverage=all --sysimage-native-code=no .buildkite/coverage-linux64/run_tests_base.jl + echo "--- Run some Julia tests in serial" + ./julia --code-coverage=all --sysimage-native-code=no .buildkite/coverage-linux64/run_tests_serial.jl test/compiler/codegen.jl + ./julia --code-coverage=all --sysimage-native-code=no .buildkite/coverage-linux64/run_tests_serial.jl test/compiler/contextual.jl + ./julia --code-coverage=all --sysimage-native-code=no .buildkite/coverage-linux64/run_tests_serial.jl test/compiler/inference.jl + ./julia --code-coverage=all --sysimage-native-code=no .buildkite/coverage-linux64/run_tests_serial.jl test/compiler/inline.jl + ./julia --code-coverage=all --sysimage-native-code=no .buildkite/coverage-linux64/run_tests_serial.jl test/compiler/interpreter_exec.jl + ./julia --code-coverage=all --sysimage-native-code=no .buildkite/coverage-linux64/run_tests_serial.jl test/compiler/irpasses.jl + ./julia --code-coverage=all --sysimage-native-code=no .buildkite/coverage-linux64/run_tests_serial.jl test/compiler/ssair.jl + ./julia --code-coverage=all --sysimage-native-code=no .buildkite/coverage-linux64/run_tests_serial.jl test/compiler/validation.jl + + echo "--- Run Julia tests in parallel with code coverage enabled" + ./julia --code-coverage=all --sysimage-native-code=no .buildkite/coverage-linux64/run_tests_parallel.jl echo "--- Process and upload coverage information" ./julia .buildkite/coverage-linux64/upload_coverage.jl diff --git a/.buildkite/coverage-linux64/run_tests_base.jl b/.buildkite/coverage-linux64/run_tests_parallel.jl similarity index 100% rename from .buildkite/coverage-linux64/run_tests_base.jl rename to .buildkite/coverage-linux64/run_tests_parallel.jl diff --git a/.buildkite/coverage-linux64/run_tests_serial.jl b/.buildkite/coverage-linux64/run_tests_serial.jl new file mode 100644 index 0000000000000..6d7380a55e402 --- /dev/null +++ b/.buildkite/coverage-linux64/run_tests_serial.jl @@ -0,0 +1,16 @@ +using Test + +const repository_root = dirname(dirname(@__DIR__)) + +for filename in ARGS + path = joinpath(repository_root, filename) + @info "Starting $(filename)" + try + @testset "$(filename)" begin + include(path) + end + catch ex + @error "" exception=(ex, catch_backtrace()) + end + @info "Finished $(filename)" +end From 26686041062abb1470e78924855cd04d2bcca843 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Tue, 13 Jul 2021 08:54:20 -0400 Subject: [PATCH 34/74] add default "auto" as option to --check-bounds (#41551) * add default "auto" as option to --check-bounds * add to NEWS (cherry picked from commit 7d0f7693fd9999f88623dc435e0f83dc9681fbd1) --- NEWS.md | 1 + base/util.jl | 2 +- doc/man/julia.1 | 4 ++-- doc/src/devdocs/boundscheck.md | 2 +- doc/src/manual/command-line-options.md | 2 +- src/jloptions.c | 7 +++++-- test/cmdlineargs.jl | 2 ++ 7 files changed, 13 insertions(+), 7 deletions(-) diff --git a/NEWS.md b/NEWS.md index c95d6896388c3..7b2d16c2d2dc5 100644 --- a/NEWS.md +++ b/NEWS.md @@ -21,6 +21,7 @@ New language features lines of code ([#40753]). * A backslash before a newline in command literals now always removes the newline, similar to standard string literals, whereas the result was not well-defined before ([#40753]). +* The default behavior of observing `@inbounds` declarations is now an option via `auto` in `--check-bounds=yes|no|auto` ([#41551]) Language changes ---------------- diff --git a/base/util.jl b/base/util.jl index 503ba5c390e1c..a8bbd92116a83 100644 --- a/base/util.jl +++ b/base/util.jl @@ -174,7 +174,7 @@ function julia_cmd(julia=joinpath(Sys.BINDIR::String, julia_exename())) elseif opts.check_bounds == 2 "no" # off else - "" # "default" + "" # default = "auto" end isempty(check_bounds) || push!(addflags, "--check-bounds=$check_bounds") end diff --git a/doc/man/julia.1 b/doc/man/julia.1 index 8e2ed9f94c76a..76277e39bc079 100644 --- a/doc/man/julia.1 +++ b/doc/man/julia.1 @@ -162,8 +162,8 @@ Set the level of debug info generation to Control whether inlining is permitted (overrides functions declared as @inline) .TP ---check-bounds={yes|no} -Emit bounds checks always or never (ignoring declarations) +--check-bounds={yes|no|auto} +Emit bounds checks always, never, or respect @inbounds declarations .TP --math-mode={ieee|user} diff --git a/doc/src/devdocs/boundscheck.md b/doc/src/devdocs/boundscheck.md index 300d7f8b72993..4f9c247db8c80 100644 --- a/doc/src/devdocs/boundscheck.md +++ b/doc/src/devdocs/boundscheck.md @@ -92,4 +92,4 @@ the last argument). ## Emit bounds checks -Julia can be launched with `--check-bounds={yes|no}` to emit bounds checks always or never (ignoring declarations). +Julia can be launched with `--check-bounds={yes|no|auto}` to emit bounds checks always, never, or respect @inbounds declarations. diff --git a/doc/src/manual/command-line-options.md b/doc/src/manual/command-line-options.md index 47d581af430e5..a0fe1849cc7b1 100644 --- a/doc/src/manual/command-line-options.md +++ b/doc/src/manual/command-line-options.md @@ -31,7 +31,7 @@ The following is a complete list of command-line switches available when launchi |`--min-optlevel={0,1,2,3}` |Set the lower bound on per-module optimization (default is 0)| |`-g`, `-g ` |Enable / Set the level of debug info generation (default level is 1 if unspecified or 2 if used without a level)| |`--inline={yes\|no}` |Control whether inlining is permitted, including overriding `@inline` declarations| -|`--check-bounds={yes\|no}` |Emit bounds checks always or never (ignoring declarations)| +|`--check-bounds={yes\|no\|auto}` |Emit bounds checks always, never, or respect @inbounds declarations| |`--math-mode={ieee,fast}` |Disallow or enable unsafe floating point optimizations (overrides @fastmath declaration)| |`--code-coverage={none\|user\|all}` |Count executions of source lines| |`--code-coverage` |equivalent to `--code-coverage=user`| diff --git a/src/jloptions.c b/src/jloptions.c index 3fb06fd4e7340..ab1af72a04c79 100644 --- a/src/jloptions.c +++ b/src/jloptions.c @@ -131,7 +131,8 @@ static const char opts[] = " (default level is 1 if unspecified or 2 if used without a level)\n" #endif " --inline={yes|no} Control whether inlining is permitted, including overriding @inline declarations\n" - " --check-bounds={yes|no} Emit bounds checks always or never (ignoring @inbounds declarations)\n" + " --check-bounds={yes|no|auto}\n" + " Emit bounds checks always, never, or respect @inbounds declarations\n" #ifdef USE_POLLY " --polly={yes|no} Enable or disable the polyhedral optimizer Polly (overrides @polly declaration)\n" #endif @@ -565,8 +566,10 @@ JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp) jl_options.check_bounds = JL_OPTIONS_CHECK_BOUNDS_ON; else if (!strcmp(optarg,"no")) jl_options.check_bounds = JL_OPTIONS_CHECK_BOUNDS_OFF; + else if (!strcmp(optarg,"auto")) + jl_options.check_bounds = JL_OPTIONS_CHECK_BOUNDS_DEFAULT; else - jl_errorf("julia: invalid argument to --check-bounds={yes|no} (%s)", optarg); + jl_errorf("julia: invalid argument to --check-bounds={yes|no|auto} (%s)", optarg); break; case opt_output_bc: jl_options.outputbc = optarg; diff --git a/test/cmdlineargs.jl b/test/cmdlineargs.jl index fbf60acdbc848..c5e82b681a3c4 100644 --- a/test/cmdlineargs.jl +++ b/test/cmdlineargs.jl @@ -396,6 +396,8 @@ let exename = `$(Base.julia_cmd()) --startup-file=no --color=no` filter!(a -> !startswith(a, "--check-bounds="), exename_default_checkbounds.exec) @test parse(Int, readchomp(`$exename_default_checkbounds -E "Int(Base.JLOptions().check_bounds)"`)) == JL_OPTIONS_CHECK_BOUNDS_DEFAULT + @test parse(Int, readchomp(`$exename -E "Int(Base.JLOptions().check_bounds)" + --check-bounds=auto`)) == JL_OPTIONS_CHECK_BOUNDS_DEFAULT @test parse(Int, readchomp(`$exename -E "Int(Base.JLOptions().check_bounds)" --check-bounds=yes`)) == JL_OPTIONS_CHECK_BOUNDS_ON @test parse(Int, readchomp(`$exename -E "Int(Base.JLOptions().check_bounds)" From 87af6211d26c6ce51f6bd5ada55488c550efe563 Mon Sep 17 00:00:00 2001 From: Nicholas Bauer Date: Thu, 15 Jul 2021 14:40:06 -0400 Subject: [PATCH 35/74] `hvncat`: Stronger argument checks (#41196) fixes #41047 (cherry picked from commit e6aca8929f7e2e8a332aa5187a1b77457e13599b) --- base/abstractarray.jl | 111 +++++++++++++++++++++++++++++------------- test/abstractarray.jl | 63 ++++++++++++++++++++++++ 2 files changed, 141 insertions(+), 33 deletions(-) diff --git a/base/abstractarray.jl b/base/abstractarray.jl index 8a2774c866dbc..1fdb441f952c8 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -2139,6 +2139,7 @@ _hvncat(dimsshape::Union{Tuple, Int}, row_first::Bool, xs::Number...) = _typed_h _hvncat(dimsshape::Union{Tuple, Int}, row_first::Bool, xs::AbstractArray...) = _typed_hvncat(promote_eltype(xs...), dimsshape, row_first, xs...) _hvncat(dimsshape::Union{Tuple, Int}, row_first::Bool, xs::AbstractArray{T}...) where T = _typed_hvncat(T, dimsshape, row_first, xs...) + typed_hvncat(T::Type, dimsshape::Tuple, row_first::Bool, xs...) = _typed_hvncat(T, dimsshape, row_first, xs...) typed_hvncat(T::Type, dim::Int, xs...) = _typed_hvncat(T, Val(dim), xs...) @@ -2155,9 +2156,9 @@ _typed_hvncat(::Type, ::Val{0}, ::AbstractArray...) = _typed_hvncat_0d_only_one( _typed_hvncat_0d_only_one() = throw(ArgumentError("a 0-dimensional array may only contain exactly one element")) -_typed_hvncat(::Type{T}, ::Val{N}) where {T, N} = Array{T, N}(undef, ntuple(x -> 0, Val(N))) - -function _typed_hvncat(::Type{T}, dims::Tuple{Vararg{Int, N}}, row_first::Bool, xs::Number...) where {T, N} +function _typed_hvncat(::Type{T}, dims::NTuple{N, Int}, row_first::Bool, xs::Number...) where {T, N} + all(>(0), dims) || + throw(ArgumentError("`dims` argument must contain positive integers")) A = Array{T, N}(undef, dims...) lengtha = length(A) # Necessary to store result because throw blocks are being deoptimized right now, which leads to excessive allocations lengthx = length(xs) # Cuts from 3 allocations to 1. @@ -2194,9 +2195,28 @@ function hvncat_fill!(A::Array, row_first::Bool, xs::Tuple) end _typed_hvncat(T::Type, dim::Int, ::Bool, xs...) = _typed_hvncat(T, Val(dim), xs...) # catches from _hvncat type promoters + +function _typed_hvncat(::Type{T}, ::Val{N}) where {T, N} + N < 0 && + throw(ArgumentError("concatenation dimension must be nonnegative")) + return Array{T, N}(undef, ntuple(x -> 0, Val(N))) +end + +function _typed_hvncat(T::Type, ::Val{N}, xs::Number...) where N + N < 0 && + throw(ArgumentError("concatenation dimension must be nonnegative")) + A = cat_similar(xs[1], T, (ntuple(x -> 1, Val(N - 1))..., length(xs))) + hvncat_fill!(A, false, xs) + return A +end + function _typed_hvncat(::Type{T}, ::Val{N}, as::AbstractArray...) where {T, N} # optimization for arrays that can be concatenated by copying them linearly into the destination - # conditions: the elements must all have 1- or 0-length dimensions above N + # conditions: the elements must all have 1-length dimensions above N + length(as) > 0 || + throw(ArgumentError("must have at least one element")) + N < 0 && + throw(ArgumentError("concatenation dimension must be nonnegative")) for a ∈ as ndims(a) <= N || all(x -> size(a, x) == 1, (N + 1):ndims(a)) || return _typed_hvncat(T, (ntuple(x -> 1, N - 1)..., length(as), 1), false, as...) @@ -2206,10 +2226,13 @@ function _typed_hvncat(::Type{T}, ::Val{N}, as::AbstractArray...) where {T, N} nd = max(N, ndims(as[1])) Ndim = 0 - for i ∈ 1:lastindex(as) - Ndim += cat_size(as[i], N) - for d ∈ 1:N - 1 - cat_size(as[1], d) == cat_size(as[i], d) || throw(ArgumentError("mismatched size along axis $d in element $i")) + for i ∈ eachindex(as) + a = as[i] + Ndim += size(a, N) + nd = max(nd, ndims(a)) + for d ∈ 1:N-1 + size(a, d) == size(as[1], d) || + throw(ArgumentError("all dimensions of element $i other than $N must be of length 1")) end end @@ -2225,17 +2248,20 @@ function _typed_hvncat(::Type{T}, ::Val{N}, as::AbstractArray...) where {T, N} end function _typed_hvncat(::Type{T}, ::Val{N}, as...) where {T, N} - # optimization for scalars and 1-length arrays that can be concatenated by copying them linearly - # into the destination + length(as) > 0 || + throw(ArgumentError("must have at least one element")) + N < 0 && + throw(ArgumentError("concatenation dimension must be nonnegative")) nd = N Ndim = 0 - for a ∈ as - if a isa AbstractArray - cat_size(a, N) == length(a) || - throw(ArgumentError("all dimensions of elements other than $N must be of length 1")) - nd = max(nd, cat_ndims(a)) - end + for i ∈ eachindex(as) + a = as[i] Ndim += cat_size(a, N) + nd = max(nd, cat_ndims(a)) + for d ∈ 1:N-1 + cat_size(a, d) == 1 || + throw(ArgumentError("all dimensions of element $i other than $N must be of length 1")) + end end A = Array{T, nd}(undef, ntuple(x -> 1, N - 1)..., Ndim, ntuple(x -> 1, nd - N)...) @@ -2279,7 +2305,12 @@ function _typed_hvncat_1d(::Type{T}, ds::Int, ::Val{row_first}, as...) where {T, end end -function _typed_hvncat(::Type{T}, dims::Tuple{Vararg{Int, N}}, row_first::Bool, as...) where {T, N} +function _typed_hvncat(::Type{T}, dims::NTuple{N, Int}, row_first::Bool, as...) where {T, N} + length(as) > 0 || + throw(ArgumentError("must have at least one element")) + all(>(0), dims) || + throw(ArgumentError("`dims` argument must contain positive integers")) + d1 = row_first ? 2 : 1 d2 = row_first ? 1 : 2 @@ -2294,7 +2325,9 @@ function _typed_hvncat(::Type{T}, dims::Tuple{Vararg{Int, N}}, row_first::Bool, currentdims = zeros(Int, nd) blockcount = 0 + elementcount = 0 for i ∈ eachindex(as) + elementcount += cat_length(as[i]) currentdims[d1] += cat_size(as[i], d1) if currentdims[d1] == outdims[d1] currentdims[d1] = 0 @@ -2324,14 +2357,9 @@ function _typed_hvncat(::Type{T}, dims::Tuple{Vararg{Int, N}}, row_first::Bool, end end - # calling sum() leads to 3 extra allocations - len = 0 - for a ∈ as - len += cat_length(a) - end outlen = prod(outdims) - outlen == 0 && ArgumentError("too few elements in arguments, unable to infer dimensions") |> throw - len == outlen || ArgumentError("too many elements in arguments; expected $(outlen), got $(len)") |> throw + elementcount == outlen || + throw(ArgumentError("mismatched number of elements; expected $(outlen), got $(elementcount)")) # copy into final array A = cat_similar(as[1], T, outdims) @@ -2350,14 +2378,22 @@ function _typed_hvncat(T::Type, shape::Tuple{Tuple}, row_first::Bool, xs...) return _typed_hvncat_1d(T, shape[1][1], Val(row_first), xs...) end -function _typed_hvncat(T::Type, shape::NTuple{N, Tuple}, row_first::Bool, as...) where {N} +function _typed_hvncat(::Type{T}, shape::NTuple{N, Tuple}, row_first::Bool, as...) where {T, N} + length(as) > 0 || + throw(ArgumentError("must have at least one element")) + all(>(0), tuple((shape...)...)) || + throw(ArgumentError("`shape` argument must consist of positive integers")) + d1 = row_first ? 2 : 1 d2 = row_first ? 1 : 2 - shape = collect(shape) # saves allocations later - shapelength = shape[end][1] + shapev = collect(shape) # saves allocations later + all(!isempty, shapev) || + throw(ArgumentError("each level of `shape` argument must have at least one value")) + length(shapev[end]) == 1 || + throw(ArgumentError("last level of shape must contain only one integer")) + shapelength = shapev[end][1] lengthas = length(as) shapelength == lengthas || throw(ArgumentError("number of elements does not match shape; expected $(shapelength), got $lengthas)")) - # discover dimensions nd = max(N, cat_ndims(as[1])) outdims = zeros(Int, nd) @@ -2365,7 +2401,9 @@ function _typed_hvncat(T::Type, shape::NTuple{N, Tuple}, row_first::Bool, as...) blockcounts = zeros(Int, nd) shapepos = ones(Int, nd) + elementcount = 0 for i ∈ eachindex(as) + elementcount += cat_length(as[i]) wasstartblock = false for d ∈ 1:N ad = (d < 3 && row_first) ? (d == 1 ? 2 : 1) : d @@ -2375,27 +2413,34 @@ function _typed_hvncat(T::Type, shape::NTuple{N, Tuple}, row_first::Bool, as...) if d == 1 || i == 1 || wasstartblock currentdims[d] += dsize elseif dsize != cat_size(as[i - 1], ad) - throw(ArgumentError("""argument $i has a mismatched number of elements along axis $ad; \ - expected $(cat_size(as[i - 1], ad)), got $dsize""")) + throw(ArgumentError("argument $i has a mismatched number of elements along axis $ad; \ + expected $(cat_size(as[i - 1], ad)), got $dsize")) end wasstartblock = blockcounts[d] == 1 # remember for next dimension - isendblock = blockcounts[d] == shape[d][shapepos[d]] + isendblock = blockcounts[d] == shapev[d][shapepos[d]] if isendblock if outdims[d] == 0 outdims[d] = currentdims[d] elseif outdims[d] != currentdims[d] - throw(ArgumentError("""argument $i has a mismatched number of elements along axis $ad; \ - expected $(abs(outdims[d] - (currentdims[d] - dsize))), got $dsize""")) + throw(ArgumentError("argument $i has a mismatched number of elements along axis $ad; \ + expected $(abs(outdims[d] - (currentdims[d] - dsize))), got $dsize")) end currentdims[d] = 0 blockcounts[d] = 0 shapepos[d] += 1 + d > 1 && (blockcounts[d - 1] == 0 || + throw(ArgumentError("shape in level $d is inconsistent; level counts must nest \ + evenly into each other"))) end end end + outlen = prod(outdims) + elementcount == outlen || + throw(ArgumentError("mismatched number of elements; expected $(outlen), got $(elementcount)")) + if row_first outdims[1], outdims[2] = outdims[2], outdims[1] end diff --git a/test/abstractarray.jl b/test/abstractarray.jl index a1c6dd1b22ce7..05f93805953dd 100644 --- a/test/abstractarray.jl +++ b/test/abstractarray.jl @@ -1390,6 +1390,69 @@ using Base: typed_hvncat @test [v v;;; fill(v, 1, 2)] == fill(v, 1, 2, 2) end + # dims form + for v ∈ ((), (1,), ([1],), (1, [1]), ([1], 1), ([1], [1])) + # reject dimension < 0 + @test_throws ArgumentError hvncat(-1, v...) + + # reject shape tuple with no elements + @test_throws ArgumentError hvncat(((),), true, v...) + end + + # reject dims or shape with negative or zero values + for v1 ∈ (-1, 0, 1) + for v2 ∈ (-1, 0, 1) + v1 == v2 == 1 && continue + for v3 ∈ ((), (1,), ([1],), (1, [1]), ([1], 1), ([1], [1])) + @test_throws ArgumentError hvncat((v1, v2), true, v3...) + @test_throws ArgumentError hvncat(((v1,), (v2,)), true, v3...) + end + end + end + + for v ∈ ((1, [1]), ([1], 1), ([1], [1])) + # reject shape with more than one end value + @test_throws ArgumentError hvncat(((1, 1),), true, v...) + end + + for v ∈ ((1, 2, 3), (1, 2, [3]), ([1], [2], [3])) + # reject shape with more values in later level + @test_throws ArgumentError hvncat(((2, 1), (1, 1, 1)), true, v...) + end + + # reject shapes that don't nest evenly between levels (e.g. 1 + 2 does not fit into 2) + @test_throws ArgumentError hvncat(((1, 2, 1), (2, 2), (4,)), true, [1 2], [3], [4], [1 2; 3 4]) + + # zero-length arrays are handled appropriately + @test [zeros(Int, 1, 2, 0) ;;; 1 3] == [1 3;;;] + @test [[] ;;; [] ;;; []] == Array{Any}(undef, 0, 1, 3) + @test [[] ; 1 ;;; 2 ; []] == [1 ;;; 2] + @test [[] ; [] ;;; [] ; []] == Array{Any}(undef, 0, 1, 2) + @test [[] ; 1 ;;; 2] == [1 ;;; 2] + @test [[] ; [] ;;; [] ;;; []] == Array{Any}(undef, 0, 1, 3) + z = zeros(Int, 0, 0, 0) + [z z ; z ;;; z ;;; z] == Array{Int}(undef, 0, 0, 0) + + for v1 ∈ (zeros(Int, 0, 0), zeros(Int, 0, 0, 0, 0), zeros(Int, 0, 0, 0, 0, 0, 0, 0)) + for v2 ∈ (1, [1]) + for v3 ∈ (2, [2]) + @test_throws ArgumentError [v1 ;;; v2] + @test_throws ArgumentError [v1 ;;; v2 v3] + @test_throws ArgumentError [v1 v1 ;;; v2 v3] + end + end + end + v1 = zeros(Int, 0, 0, 0) + for v2 ∈ (1, [1]) + for v3 ∈ (2, [2]) + # current behavior, not potentially dangerous. + # should throw error like above loop + @test [v1 ;;; v2 v3] == [v2 v3;;;] + @test_throws ArgumentError [v1 ;;; v2] + @test_throws ArgumentError [v1 v1 ;;; v2 v3] + end + end + # 0-dimension behaviors # exactly one argument, placed in an array # if already an array, copy, with type conversion as necessary From 81d8c0c11b7516ec1d262b36736ef46465610ccf Mon Sep 17 00:00:00 2001 From: Nicholas Bauer Date: Fri, 16 Jul 2021 13:41:41 -0400 Subject: [PATCH 36/74] `hvncat`: Ensure output ndims are >= the ndims of input arrays (#41201) (cherry picked from commit a2f5fe59d72736bfda7b3004f1c4bb58918fa94c) --- base/abstractarray.jl | 127 ++++++++++++++++++++++-------------------- test/abstractarray.jl | 19 +++++++ 2 files changed, 86 insertions(+), 60 deletions(-) diff --git a/base/abstractarray.jl b/base/abstractarray.jl index 1fdb441f952c8..f5eb075241dc6 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -2156,44 +2156,6 @@ _typed_hvncat(::Type, ::Val{0}, ::AbstractArray...) = _typed_hvncat_0d_only_one( _typed_hvncat_0d_only_one() = throw(ArgumentError("a 0-dimensional array may only contain exactly one element")) -function _typed_hvncat(::Type{T}, dims::NTuple{N, Int}, row_first::Bool, xs::Number...) where {T, N} - all(>(0), dims) || - throw(ArgumentError("`dims` argument must contain positive integers")) - A = Array{T, N}(undef, dims...) - lengtha = length(A) # Necessary to store result because throw blocks are being deoptimized right now, which leads to excessive allocations - lengthx = length(xs) # Cuts from 3 allocations to 1. - if lengtha != lengthx - throw(ArgumentError("argument count does not match specified shape (expected $lengtha, got $lengthx)")) - end - hvncat_fill!(A, row_first, xs) - return A -end - -function hvncat_fill!(A::Array, row_first::Bool, xs::Tuple) - # putting these in separate functions leads to unnecessary allocations - if row_first - nr, nc = size(A, 1), size(A, 2) - nrc = nr * nc - na = prod(size(A)[3:end]) - k = 1 - for d ∈ 1:na - dd = nrc * (d - 1) - for i ∈ 1:nr - Ai = dd + i - for j ∈ 1:nc - A[Ai] = xs[k] - k += 1 - Ai += nr - end - end - end - else - for k ∈ eachindex(xs) - A[k] = xs[k] - end - end -end - _typed_hvncat(T::Type, dim::Int, ::Bool, xs...) = _typed_hvncat(T, Val(dim), xs...) # catches from _hvncat type promoters function _typed_hvncat(::Type{T}, ::Val{N}) where {T, N} @@ -2219,20 +2181,18 @@ function _typed_hvncat(::Type{T}, ::Val{N}, as::AbstractArray...) where {T, N} throw(ArgumentError("concatenation dimension must be nonnegative")) for a ∈ as ndims(a) <= N || all(x -> size(a, x) == 1, (N + 1):ndims(a)) || - return _typed_hvncat(T, (ntuple(x -> 1, N - 1)..., length(as), 1), false, as...) + return _typed_hvncat(T, (ntuple(x -> 1, Val(N - 1))..., length(as), 1), false, as...) # the extra 1 is to avoid an infinite cycle end - nd = max(N, ndims(as[1])) + nd = N Ndim = 0 for i ∈ eachindex(as) - a = as[i] - Ndim += size(a, N) - nd = max(nd, ndims(a)) - for d ∈ 1:N-1 - size(a, d) == size(as[1], d) || - throw(ArgumentError("all dimensions of element $i other than $N must be of length 1")) + Ndim += cat_size(as[i], N) + nd = max(nd, cat_ndims(as[i])) + for d ∈ 1:N - 1 + cat_size(as[1], d) == cat_size(as[i], d) || throw(ArgumentError("mismatched size along axis $d in element $i")) end end @@ -2255,16 +2215,15 @@ function _typed_hvncat(::Type{T}, ::Val{N}, as...) where {T, N} nd = N Ndim = 0 for i ∈ eachindex(as) - a = as[i] - Ndim += cat_size(a, N) - nd = max(nd, cat_ndims(a)) + Ndim += cat_size(as[i], N) + nd = max(nd, cat_ndims(as[i])) for d ∈ 1:N-1 - cat_size(a, d) == 1 || + cat_size(as[i], d) == 1 || throw(ArgumentError("all dimensions of element $i other than $N must be of length 1")) end end - A = Array{T, nd}(undef, ntuple(x -> 1, N - 1)..., Ndim, ntuple(x -> 1, nd - N)...) + A = Array{T, nd}(undef, ntuple(x -> 1, Val(N - 1))..., Ndim, ntuple(x -> 1, nd - N)...) k = 1 for a ∈ as @@ -2280,7 +2239,6 @@ function _typed_hvncat(::Type{T}, ::Val{N}, as...) where {T, N} return A end - # 0-dimensional cases for balanced and unbalanced hvncat method _typed_hvncat(T::Type, ::Tuple{}, ::Bool, x...) = _typed_hvncat(T, Val(0), x...) @@ -2305,7 +2263,51 @@ function _typed_hvncat_1d(::Type{T}, ds::Int, ::Val{row_first}, as...) where {T, end end -function _typed_hvncat(::Type{T}, dims::NTuple{N, Int}, row_first::Bool, as...) where {T, N} +function _typed_hvncat(::Type{T}, dims::NTuple{N, Int}, row_first::Bool, xs::Number...) where {T, N} + all(>(0), dims) || + throw(ArgumentError("`dims` argument must contain positive integers")) + A = Array{T, N}(undef, dims...) + lengtha = length(A) # Necessary to store result because throw blocks are being deoptimized right now, which leads to excessive allocations + lengthx = length(xs) # Cuts from 3 allocations to 1. + if lengtha != lengthx + throw(ArgumentError("argument count does not match specified shape (expected $lengtha, got $lengthx)")) + end + hvncat_fill!(A, row_first, xs) + return A +end + +function hvncat_fill!(A::Array, row_first::Bool, xs::Tuple) + # putting these in separate functions leads to unnecessary allocations + if row_first + nr, nc = size(A, 1), size(A, 2) + nrc = nr * nc + na = prod(size(A)[3:end]) + k = 1 + for d ∈ 1:na + dd = nrc * (d - 1) + for i ∈ 1:nr + Ai = dd + i + for j ∈ 1:nc + A[Ai] = xs[k] + k += 1 + Ai += nr + end + end + end + else + for k ∈ eachindex(xs) + A[k] = xs[k] + end + end +end + +function _typed_hvncat(T::Type, dims::NTuple{N, Int}, row_first::Bool, as...) where {N} + # function barrier after calculating the max is necessary for high performance + nd = max(maximum(cat_ndims(a) for a ∈ as), N) + return _typed_hvncat_dims(T, (dims..., ntuple(x -> 1, nd - N)...), row_first, as) +end + +function _typed_hvncat_dims(::Type{T}, dims::NTuple{N, Int}, row_first::Bool, as::Tuple) where {T, N} length(as) > 0 || throw(ArgumentError("must have at least one element")) all(>(0), dims) || @@ -2314,16 +2316,14 @@ function _typed_hvncat(::Type{T}, dims::NTuple{N, Int}, row_first::Bool, as...) d1 = row_first ? 2 : 1 d2 = row_first ? 1 : 2 - # discover dimensions - nd = max(N, cat_ndims(as[1])) - outdims = zeros(Int, nd) + outdims = zeros(Int, N) # discover number of rows or columns for i ∈ 1:dims[d1] outdims[d1] += cat_size(as[i], d1) end - currentdims = zeros(Int, nd) + currentdims = zeros(Int, N) blockcount = 0 elementcount = 0 for i ∈ eachindex(as) @@ -2331,11 +2331,11 @@ function _typed_hvncat(::Type{T}, dims::NTuple{N, Int}, row_first::Bool, as...) currentdims[d1] += cat_size(as[i], d1) if currentdims[d1] == outdims[d1] currentdims[d1] = 0 - for d ∈ (d2, 3:nd...) + for d ∈ (d2, 3:N...) currentdims[d] += cat_size(as[i], d) if outdims[d] == 0 # unfixed dimension blockcount += 1 - if blockcount == (d > length(dims) ? 1 : dims[d]) # last expected member of dimension + if blockcount == dims[d] outdims[d] = currentdims[d] currentdims[d] = 0 blockcount = 0 @@ -2378,7 +2378,13 @@ function _typed_hvncat(T::Type, shape::Tuple{Tuple}, row_first::Bool, xs...) return _typed_hvncat_1d(T, shape[1][1], Val(row_first), xs...) end -function _typed_hvncat(::Type{T}, shape::NTuple{N, Tuple}, row_first::Bool, as...) where {T, N} +function _typed_hvncat(T::Type, shape::NTuple{N, Tuple}, row_first::Bool, as...) where {N} + # function barrier after calculating the max is necessary for high performance + nd = max(maximum(cat_ndims(a) for a ∈ as), N) + return _typed_hvncat_shape(T, (shape..., ntuple(x -> shape[end], nd - N)...), row_first, as) +end + +function _typed_hvncat_shape(::Type{T}, shape::NTuple{N, Tuple}, row_first, as::Tuple) where {T, N} length(as) > 0 || throw(ArgumentError("must have at least one element")) all(>(0), tuple((shape...)...)) || @@ -2386,6 +2392,7 @@ function _typed_hvncat(::Type{T}, shape::NTuple{N, Tuple}, row_first::Bool, as.. d1 = row_first ? 2 : 1 d2 = row_first ? 1 : 2 + shapev = collect(shape) # saves allocations later all(!isempty, shapev) || throw(ArgumentError("each level of `shape` argument must have at least one value")) diff --git a/test/abstractarray.jl b/test/abstractarray.jl index 05f93805953dd..b2b53d33db8ec 100644 --- a/test/abstractarray.jl +++ b/test/abstractarray.jl @@ -1390,6 +1390,25 @@ using Base: typed_hvncat @test [v v;;; fill(v, 1, 2)] == fill(v, 1, 2, 2) end + # output dimensions are maximum of input dimensions and concatenation dimension + begin + v1 = fill(1, 1, 1) + v2 = fill(1, 1, 1, 1, 1) + v3 = fill(1, 1, 2, 1, 1) + @test [v1 ;;; v2] == [1 ;;; 1 ;;;;] + @test [v2 ;;; v1] == [1 ;;; 1 ;;;;] + @test [v3 ;;; v1 v1] == [1 1 ;;; 1 1 ;;;;] + @test [v1 v1 ;;; v3] == [1 1 ;;; 1 1 ;;;;] + @test [v2 v1 ;;; v1 v1] == [1 1 ;;; 1 1 ;;;;] + @test [v1 v1 ;;; v1 v2] == [1 1 ;;; 1 1 ;;;;] + @test [v2 ;;; 1] == [1 ;;; 1 ;;;;] + @test [1 ;;; v2] == [1 ;;; 1 ;;;;] + @test [v3 ;;; 1 v1] == [1 1 ;;; 1 1 ;;;;] + @test [v1 1 ;;; v3] == [1 1 ;;; 1 1 ;;;;] + @test [v2 1 ;;; v1 v1] == [1 1 ;;; 1 1 ;;;;] + @test [v1 1 ;;; v1 v2] == [1 1 ;;; 1 1 ;;;;] + end + # dims form for v ∈ ((), (1,), ([1],), (1, [1]), ([1], 1), ([1], [1])) # reject dimension < 0 From 31aad85920486923fbaf72174d7c9685c99d365e Mon Sep 17 00:00:00 2001 From: Andreas Noack Date: Wed, 14 Jul 2021 08:08:27 +0200 Subject: [PATCH 37/74] Revert "Extend `Eigen` to keep additional information from `geevx` (#38483)" This reverts commit 9d3a7c47df972b1108b5a49d2c5ce493635bbadf. --- stdlib/LinearAlgebra/src/eigen.jl | 113 ++++++------------------------ 1 file changed, 21 insertions(+), 92 deletions(-) diff --git a/stdlib/LinearAlgebra/src/eigen.jl b/stdlib/LinearAlgebra/src/eigen.jl index 3341a2a9bc744..943a5ca0cdf3d 100644 --- a/stdlib/LinearAlgebra/src/eigen.jl +++ b/stdlib/LinearAlgebra/src/eigen.jl @@ -17,7 +17,7 @@ Iterating the decomposition produces the components `F.values` and `F.vectors`. # Examples ```jldoctest julia> F = eigen([1.0 0.0 0.0; 0.0 3.0 0.0; 0.0 0.0 18.0]) -Eigen{Float64, Float64, Matrix{Float64}, Vector{Float64}, Vector{Float64}} +Eigen{Float64, Float64, Matrix{Float64}, Vector{Float64}} values: 3-element Vector{Float64}: 1.0 @@ -47,18 +47,14 @@ julia> vals == F.values && vecs == F.vectors true ``` """ -struct Eigen{T,V,S<:AbstractMatrix,U<:AbstractVector,R<:AbstractVector} <: Factorization{T} +struct Eigen{T,V,S<:AbstractMatrix,U<:AbstractVector} <: Factorization{T} values::U vectors::S - vectorsl::S - unitary::Bool - rconde::R - rcondv::R - Eigen{T,V,S,U,R}(values::AbstractVector{V}, vectors::AbstractMatrix{T}, vectorsl::AbstractMatrix{T}, unitary::Bool, rconde::R, rcondv::R) where {T,V,S,U,R} = - new(values, vectors, vectorsl, unitary, rconde, rcondv) + Eigen{T,V,S,U}(values::AbstractVector{V}, vectors::AbstractMatrix{T}) where {T,V,S,U} = + new(values, vectors) end -Eigen(values::AbstractVector{V}, vectors::AbstractMatrix{T}, vectorsl=vectors, uni=true, rce=zeros(real(T),0), rcv=zeros(real(T), 0)) where {T,V} = - Eigen{T,V,typeof(vectors),typeof(values),typeof(rce)}(values, vectors, vectorsl, uni, rce, rcv) +Eigen(values::AbstractVector{V}, vectors::AbstractMatrix{T}) where {T,V} = + Eigen{T,V,typeof(vectors),typeof(values)}(values, vectors) # Generalized eigenvalue problem. """ @@ -137,21 +133,10 @@ function sorteig!(λ::AbstractVector, X::AbstractMatrix, sortby::Union{Function, if sortby !== nothing && !issorted(λ, by=sortby) p = sortperm(λ; alg=QuickSort, by=sortby) permute!(λ, p) - !isempty(X) && Base.permutecols!!(X, copy(p)) + Base.permutecols!!(X, p) end return λ, X end -function sorteig!(λ::AbstractVector, X::AbstractMatrix, sortby::Union{Function,Nothing}, Y::AbstractMatrix, rconde::AbstractVector, rcondv::AbstractVector) - if sortby !== nothing && !issorted(λ, by=sortby) - p = sortperm(λ; alg=QuickSort, by=sortby) - permute!(λ, p) - !isempty(rconde) && permute!(rconde, p) - !isempty(rcondv) && permute!(rcondv, p) - !isempty(X) && Base.permutecols!!(X, copy(p)) - !isempty(Y) && X !== Y && Base.permutecols!!(Y, p) - end - return λ, X, Y, false, rconde, rcondv -end sorteig!(λ::AbstractVector, sortby::Union{Function,Nothing}=eigsortby) = sortby === nothing ? λ : sort!(λ, by=sortby) """ @@ -160,32 +145,12 @@ sorteig!(λ::AbstractVector, sortby::Union{Function,Nothing}=eigsortby) = sortby Same as [`eigen`](@ref), but saves space by overwriting the input `A` (and `B`), instead of creating a copy. """ -function eigen!(A::StridedMatrix{T}; permute::Bool=true, scale::Bool=true, sortby::Union{Function,Nothing}=eigsortby, jvl::Bool=false, jvr::Bool=true, jce::Bool=false, jcv::Bool=false) where T<:BlasReal +function eigen!(A::StridedMatrix{T}; permute::Bool=true, scale::Bool=true, sortby::Union{Function,Nothing}=eigsortby) where T<:BlasReal n = size(A, 2) n == 0 && return Eigen(zeros(T, 0), zeros(T, 0, 0)) issymmetric(A) && return eigen!(Symmetric(A), sortby=sortby) - - balance = permute ? (scale ? 'B' : 'P') : (scale ? 'S' : 'N') - jobvl = jvl || jce ? 'V' : 'N' - jobvr = jvr || jce ? 'V' : 'N' - sense = jce && jcv ? 'B' : jce ? 'E' : jcv ? 'V' : 'N' - A, WR, WI, VL, VR, _, _, scale, abnrm, rconde, rcondv = LAPACK.geevx!(balance, jobvl, jobvr, sense, A) - if iszero(WI) - evecr = VR - evecl = VL - evals = WR - else - evecr = complexeig(WI, VR) - evecl = complexeig(WI, VL) - evals = complex.(WR, WI) - end - rconde = jce ? inv.(rconde) : zeros(T, 0) - rcondv = jcv ? inv.(rcondv) : zeros(T, 0) - return Eigen(sorteig!(evals, evecr, sortby, evecl, rconde, rcondv)...) -end - -function complexeig(WI::Vector{T}, VR::Matrix{T}) where T - n = min(size(VR)...) + A, WR, WI, VL, VR, _ = LAPACK.geevx!(permute ? (scale ? 'B' : 'P') : (scale ? 'S' : 'N'), 'N', 'V', 'N', A) + iszero(WI) && return Eigen(sorteig!(WR, VR, sortby)...) evec = zeros(Complex{T}, n, n) j = 1 while j <= n @@ -200,19 +165,15 @@ function complexeig(WI::Vector{T}, VR::Matrix{T}) where T end j += 1 end - evec + return Eigen(sorteig!(complex.(WR, WI), evec, sortby)...) end -function eigen!(A::StridedMatrix{T}; permute::Bool=true, scale::Bool=true, sortby::Union{Function,Nothing}=eigsortby, jvl::Bool=false, jvr::Bool=true, jce::Bool=false, jcv::Bool=false) where T<:BlasComplex +function eigen!(A::StridedMatrix{T}; permute::Bool=true, scale::Bool=true, sortby::Union{Function,Nothing}=eigsortby) where T<:BlasComplex n = size(A, 2) n == 0 && return Eigen(zeros(T, 0), zeros(T, 0, 0)) ishermitian(A) && return eigen!(Hermitian(A), sortby=sortby) - balance = permute ? (scale ? 'B' : 'P') : (scale ? 'S' : 'N') - jobvl = jvl || jce ? 'V' : 'N' - jobvr = jvr || jce ? 'V' : 'N' - sense = jce && jcv ? 'B' : jce ? 'E' : jcv ? 'V' : 'N' - A, W, VL, VR, _, _, scale, abnrm, rconde, rcondv = LAPACK.geevx!(balance, jobvl, jobvr, sense, A) - return Eigen(sorteig!(W, VR, sortby, VL, rconde, rcondv)...) + eval, evec = LAPACK.geevx!(permute ? (scale ? 'B' : 'P') : (scale ? 'S' : 'N'), 'N', 'V', 'N', A)[[2,4]] + return Eigen(sorteig!(eval, evec, sortby)...) end """ @@ -240,7 +201,7 @@ accept a `sortby` keyword. # Examples ```jldoctest julia> F = eigen([1.0 0.0 0.0; 0.0 3.0 0.0; 0.0 0.0 18.0]) -Eigen{Float64, Float64, Matrix{Float64}, Vector{Float64}, Vector{Float64}} +Eigen{Float64, Float64, Matrix{Float64}, Vector{Float64}} values: 3-element Vector{Float64}: 1.0 @@ -270,10 +231,10 @@ julia> vals == F.values && vecs == F.vectors true ``` """ -function eigen(A::AbstractMatrix{T}; permute::Bool=true, scale::Bool=true, sortby::Union{Function,Nothing}=eigsortby, jvl::Bool=false, jvr::Bool=true, jce::Bool=false, jcv::Bool=false) where T +function eigen(A::AbstractMatrix{T}; permute::Bool=true, scale::Bool=true, sortby::Union{Function,Nothing}=eigsortby) where T AA = copy_oftype(A, eigtype(T)) isdiag(AA) && return eigen(Diagonal(AA); permute=permute, scale=scale, sortby=sortby) - return eigen!(AA; permute=permute, scale=scale, sortby=sortby, jvl=jvl, jvr=jvr, jce=jce, jcv=jcv) + return eigen!(AA; permute=permute, scale=scale, sortby=sortby) end eigen(x::Number) = Eigen([x], fill(one(x), 1, 1)) @@ -459,19 +420,7 @@ function eigmin(A::Union{Number, AbstractMatrix}; minimum(v) end -""" - spectral(f, F::Eigen) - -Construct a matrix from an eigen-decomposition `F` by applying the function to -the spectrum (diagonal) of `F`. -""" -function spectral(f, A::Eigen) - d = Diagonal(f.(A.values)) - v = A.vectors - vd = v * d - A.unitary ? vd * v' : vd / v -end -inv(A::Eigen) = spectral(inv, A) +inv(A::Eigen) = A.vectors * inv(Diagonal(A.values)) / A.vectors det(A::Eigen) = prod(A.values) # Generalized eigenproblem @@ -661,28 +610,8 @@ function show(io::IO, mime::MIME{Symbol("text/plain")}, F::Union{Eigen,Generaliz summary(io, F); println(io) println(io, "values:") show(io, mime, F.values) - if !isdefined(F, :vectorsl) || (!isempty(F.vectors) && (F.vectors === F.vectorsl || isempty(F.vectorsl))) - println(io, "\nvectors:") - show(io, mime, F.vectors) - else - if !isempty(F.vectors) - println(io, "\nright vectors:") - show(io, mime, F.vectors) - end - if !isempty(F.vectorsl) - println(io, "\nleft vectors:") - show(io, mime, F.vectorsl) - end - end - if isdefined(F, :rconde) && !isempty(F.rconde) - println(io, "\ncondition values:") - show(io, mime, F.rconde) - end - if isdefined(F, :rcondv) && !isempty(F.rcondv) - println(io, "\ncondition vectors:") - show(io, mime, F.rcondv) - end - nothing + println(io, "\nvectors:") + show(io, mime, F.vectors) end function Base.hash(F::Eigen, h::UInt) @@ -698,7 +627,7 @@ end # Conversion methods ## Can we determine the source/result is Real? This is not stored in the type Eigen -AbstractMatrix(F::Eigen) = spectral(identity, F) +AbstractMatrix(F::Eigen) = F.vectors * Diagonal(F.values) / F.vectors AbstractArray(F::Eigen) = AbstractMatrix(F) Matrix(F::Eigen) = Array(AbstractArray(F)) Array(F::Eigen) = Matrix(F) From 903ae5afc0167c764ed0e01ce468a57322a1bd14 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Tue, 13 Jul 2021 14:28:29 -0700 Subject: [PATCH 38/74] CI: add the sanitizers pipelines (e.g. ASAN) to Buildkite (#41530) * Setup CI for ASAN * Launch the `sanitizers.yml` unsigned pipeline * Use a workspace directory in ./tmp * Add some log group headers to make the logs easier to navigate * Install `julia` binary inside sandbox * Double timeout * More descriptive message from sanitizer CI * Fix the path to the binary * Use addenv * Apply suggestions from code review Co-authored-by: Elliot Saba * Group ASAN related files under contrib/asan/ * Remove redundant JULIA_PRECOMPILE=1 Co-authored-by: Dilum Aluthge Co-authored-by: Elliot Saba (cherry picked from commit 84934e66db2ed0c3b888270380b4c34541d9ffc8) --- .buildkite/pipeline.yml | 5 +- .buildkite/sanitizers.yml | 34 +++++++++++++ contrib/asan/Make.user.asan | 24 ++++++++++ contrib/asan/Make.user.tools | 2 + contrib/asan/build.sh | 53 +++++++++++++++++++++ contrib/asan/check.jl | 92 ++++++++++++++++++++++++++++++++++++ 6 files changed, 209 insertions(+), 1 deletion(-) create mode 100644 .buildkite/sanitizers.yml create mode 100644 contrib/asan/Make.user.asan create mode 100644 contrib/asan/Make.user.tools create mode 100755 contrib/asan/build.sh create mode 100755 contrib/asan/check.jl diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 0dee5f2aaa3f7..99473055f2eeb 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -14,8 +14,11 @@ steps: - label: ":buildkite: Launch unsigned pipelines" commands: | + # We launch whitespace first, because we want that pipeline to finish as quickly as possible. + # The remaining unsigned pipelines are launched in alphabetical order. buildkite-agent pipeline upload .buildkite/whitespace.yml - buildkite-agent pipeline upload .buildkite/llvm_passes.yml buildkite-agent pipeline upload .buildkite/embedding.yml + buildkite-agent pipeline upload .buildkite/llvm_passes.yml + buildkite-agent pipeline upload .buildkite/sanitizers.yml agents: queue: julia diff --git a/.buildkite/sanitizers.yml b/.buildkite/sanitizers.yml new file mode 100644 index 0000000000000..f29ed4e42a4a6 --- /dev/null +++ b/.buildkite/sanitizers.yml @@ -0,0 +1,34 @@ +# These steps should only run on `sandbox.jl` machines, not `docker`-isolated ones +# since we need nestable sandboxing. The rootfs images being used here are built from +# the `.buildkite/rootfs_images/llvm-passes.jl` file. +agents: + queue: "julia" + # Only run on `sandbox.jl` machines (not `docker`-isolated ones) since we need nestable sandboxing + sandbox.jl: "true" + os: "linux" + +steps: + - label: "asan" + key: asan + plugins: + - JuliaCI/julia#v1: + version: 1.6 + - staticfloat/sandbox#v1: + rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v1/llvm-passes.tar.gz + rootfs_treehash: "f3ed53f159e8f13edfba8b20ebdb8ece73c1b8a8" + uid: 1000 + gid: 1000 + workspaces: + - "/cache/repos:/cache/repos" + # `contrib/check-asan.jl` needs a `julia` binary: + - JuliaCI/julia#v1: + version: 1.6 + commands: | + echo "--- Build julia-debug with ASAN" + contrib/asan/build.sh ./tmp/test-asan -j$${JULIA_NUM_CORES} debug + echo "--- Test that ASAN is enabled" + contrib/asan/check.jl ./tmp/test-asan/asan/usr/bin/julia-debug + timeout_in_minutes: 120 + notify: + - github_commit_status: + context: "asan" diff --git a/contrib/asan/Make.user.asan b/contrib/asan/Make.user.asan new file mode 100644 index 0000000000000..3bcc34df68323 --- /dev/null +++ b/contrib/asan/Make.user.asan @@ -0,0 +1,24 @@ +TOOLCHAIN=$(BUILDROOT)/../toolchain/usr/tools + +# use our new toolchain +USECLANG=1 +override CC=$(TOOLCHAIN)/clang +override CXX=$(TOOLCHAIN)/clang++ +export ASAN_SYMBOLIZER_PATH=$(TOOLCHAIN)/llvm-symbolizer + +USE_BINARYBUILDER_LLVM=1 + +override SANITIZE=1 +override SANITIZE_ADDRESS=1 + +# make the GC use regular malloc/frees, which are hooked by ASAN +override WITH_GC_DEBUG_ENV=1 + +# default to a debug build for better line number reporting +override JULIA_BUILD_MODE=debug + +# make ASAN consume less memory +export ASAN_OPTIONS=detect_leaks=0:fast_unwind_on_malloc=0:allow_user_segv_handler=1:malloc_context_size=2 + +# tell libblastrampoline to not use RTLD_DEEPBIND +export LBT_USE_RTLD_DEEPBIND=0 diff --git a/contrib/asan/Make.user.tools b/contrib/asan/Make.user.tools new file mode 100644 index 0000000000000..1bd6f97e39111 --- /dev/null +++ b/contrib/asan/Make.user.tools @@ -0,0 +1,2 @@ +USE_BINARYBUILDER_LLVM=1 +BUILD_LLVM_CLANG=1 diff --git a/contrib/asan/build.sh b/contrib/asan/build.sh new file mode 100755 index 0000000000000..d124e0a92f1e0 --- /dev/null +++ b/contrib/asan/build.sh @@ -0,0 +1,53 @@ +#!/bin/bash +# This file is a part of Julia. License is MIT: https://julialang.org/license +# +# Usage: +# contrib/asan/build.sh [...] +# +# Build ASAN-enabled julia. Given a workspace directory , build +# ASAN-enabled julia in /asan. Required toolss are install under +# /toolchain. This scripts also takes optional arguments +# which are passed to `make`. The default make target is `debug`. + +set -ue + +# `$WORKSPACE` is a directory in which we create `toolchain` and `asan` +# sub-directories. +WORKSPACE="$1" +shift +if [ "$WORKSPACE" = "" ]; then + echo "Workspace directory must be specified as the first argument" >&2 + exit 2 +fi + +mkdir -pv "$WORKSPACE" +WORKSPACE="$(cd "$WORKSPACE" && pwd)" +if [ "$WORKSPACE" = "" ]; then + echo "Failed to create the workspace directory." >&2 + exit 2 +fi + +HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +JULIA_HOME="$HERE/../../" + +echo +echo "Installing toolchain..." + +TOOLCHAIN="$WORKSPACE/toolchain" +if [ ! -d "$TOOLCHAIN" ]; then + make -C "$JULIA_HOME" configure O=$TOOLCHAIN + cp "$HERE/Make.user.tools" "$TOOLCHAIN/Make.user" +fi + +make -C "$TOOLCHAIN/deps" install-clang install-llvm-tools + +echo +echo "Building Julia..." + +BUILD="$WORKSPACE/asan" +if [ ! -d "$BUILD" ]; then + make -C "$JULIA_HOME" configure O="$BUILD" + cp "$HERE/Make.user.asan" "$BUILD/Make.user" +fi + +make -C "$BUILD" "$@" diff --git a/contrib/asan/check.jl b/contrib/asan/check.jl new file mode 100755 index 0000000000000..0c1e12f7f471a --- /dev/null +++ b/contrib/asan/check.jl @@ -0,0 +1,92 @@ +#!/bin/bash +# -*- mode: julia -*- +# This file is a part of Julia. License is MIT: https://julialang.org/license +# +# Usage: +# contrib/asan/check.jl +# +# Check that is built with ASAN. +# +#= +JULIA="${JULIA:-julia}" +exec "$JULIA" --startup-file=no --compile=min "${BASH_SOURCE[0]}" "$@" +=# + +function main(args = ARGS)::Int + if length(args) != 1 + @error "Expect a single argument" args + return 2 + end + julia, = args + + # It looks like double-free is easy to robustly trigger. + code = """ + @info "Testing a pattern that would trigger ASAN" + write(ARGS[1], "started") + + ptr = ccall(:malloc, Ptr{UInt}, (Csize_t,), 256) + ccall(:free, Cvoid, (Ptr{UInt},), ptr) + ccall(:free, Cvoid, (Ptr{UInt},), ptr) + + @error "Failed to trigger ASAN" + """ + + local proc + timeout = Threads.Atomic{Bool}(false) + isstarted = false + mktemp() do tmppath, tmpio + cmd = addenv( + `$julia -e $code $tmppath`, + "ASAN_OPTIONS" => + "detect_leaks=0:fast_unwind_on_malloc=0:allow_user_segv_handler=1:malloc_context_size=2", + "LBT_USE_RTLD_DEEPBIND" => "0", + ) + # Note: Ideally, we set ASAN_SYMBOLIZER_PATH here. But there is no easy + # way to find out the path from just a Julia binary. + + @debug "Starting a process" cmd + proc = run(pipeline(cmd; stdout, stderr); wait = false) + timer = Timer(10) + @sync try + @async begin + try + wait(timer) + true + catch err + err isa EOFError || rethrow() + false + end && begin + timeout[] = true + kill(proc) + end + end + wait(proc) + finally + close(timer) + end + + # At the very beginning of the process, the `julia` subprocess put a + # marker that it is successfully started. This is to avoid mixing + # non-functional `julia` binary (or even non-`julia` command) and + # correctly working `julia` with ASAN: + isstarted = read(tmpio, String) == "started" + end + + if timeout[] + @error "Timeout waiting for the subprocess" + return 1 + elseif success(proc) + @error "ASAN was not triggered" + return 1 + elseif !isstarted + @error "Failed to start the process" + return 1 + else + @info "ASAN is functional in the Julia binary `$julia`" + return 0 + end +end + +if abspath(PROGRAM_FILE) == @__FILE__ + exit(main()) +end From 98b5e4155ee1d2684ae3d63b5841de5e9975efee Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Mon, 19 Jul 2021 07:27:37 -0400 Subject: [PATCH 39/74] Move compile timing to inside `@time`'s main timing block. Fixes >100% compilation time reports (#41286) * ensure `@time`'s inner timing functions are compiled (cherry picked from commit 0dbd3f77d975edcc7e03e167f3f60aca186aff6c) --- base/timing.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/base/timing.jl b/base/timing.jl index 7af6f038ba6ea..ab7af23048305 100644 --- a/base/timing.jl +++ b/base/timing.jl @@ -205,11 +205,11 @@ macro time(ex) quote while false; end # compiler heuristic: compile this block (alter this if the heuristic changes) local stats = gc_num() - local compile_elapsedtime = cumulative_compile_time_ns_before() local elapsedtime = time_ns() + local compile_elapsedtime = cumulative_compile_time_ns_before() local val = $(esc(ex)) - elapsedtime = time_ns() - elapsedtime compile_elapsedtime = cumulative_compile_time_ns_after() - compile_elapsedtime + elapsedtime = time_ns() - elapsedtime local diff = GC_Diff(gc_num(), stats) time_print(elapsedtime, diff.allocd, diff.total_time, gc_alloc_count(diff), compile_elapsedtime, true) val @@ -251,11 +251,11 @@ macro timev(ex) quote while false; end # compiler heuristic: compile this block (alter this if the heuristic changes) local stats = gc_num() - local compile_elapsedtime = cumulative_compile_time_ns_before() local elapsedtime = time_ns() + local compile_elapsedtime = cumulative_compile_time_ns_before() local val = $(esc(ex)) - elapsedtime = time_ns() - elapsedtime compile_elapsedtime = cumulative_compile_time_ns_after() - compile_elapsedtime + elapsedtime = time_ns() - elapsedtime local diff = GC_Diff(gc_num(), stats) timev_print(elapsedtime, diff, compile_elapsedtime) val From 01f53de2c4ebe70337991e091b81d7ba71ae0765 Mon Sep 17 00:00:00 2001 From: Jakob Nybo Nissen Date: Mon, 19 Jul 2021 13:28:03 +0200 Subject: [PATCH 40/74] Do not error when showing invalid enums (#40042) (#41596) (cherry picked from commit 02807b279a5e6d5acaeb7095e4c0527e2a5c190e) --- base/Enums.jl | 10 ++++++++-- test/enums.jl | 7 +++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/base/Enums.jl b/base/Enums.jl index 06860402fbcb1..7b5e9587d5f6c 100644 --- a/base/Enums.jl +++ b/base/Enums.jl @@ -25,10 +25,16 @@ Base.isless(x::T, y::T) where {T<:Enum} = isless(basetype(T)(x), basetype(T)(y)) Base.Symbol(x::Enum) = namemap(typeof(x))[Integer(x)]::Symbol -Base.print(io::IO, x::Enum) = print(io, Symbol(x)) +function _symbol(x::Enum) + names = namemap(typeof(x)) + x = Integer(x) + get(() -> Symbol(""), names, x)::Symbol +end + +Base.print(io::IO, x::Enum) = print(io, _symbol(x)) function Base.show(io::IO, x::Enum) - sym = Symbol(x) + sym = _symbol(x) if !(get(io, :compact, false)::Bool) from = get(io, :module, Main) def = typeof(x).name.module diff --git a/test/enums.jl b/test/enums.jl index d3c585678c572..5a83e1b4dfa42 100644 --- a/test/enums.jl +++ b/test/enums.jl @@ -143,6 +143,10 @@ let io = IOBuffer() @test String(take!(io)) == sprint(print, Fruit) end +# Test printing of invalid enums +@test repr("text/plain", reinterpret(Fruit, Int32(11))) == "::Fruit = 11" +@test repr("text/plain", reinterpret(Fruit, Int32(-5))) == "::Fruit = -5" + @enum LogLevel DEBUG INFO WARN ERROR CRITICAL @test DEBUG < CRITICAL @@ -160,6 +164,9 @@ end @test repr("text/plain", sevn) == "$(string(sevn))::UI8 = 0x07" @test repr("text/plain", fiftn) == "$(string(fiftn))::UI8 = 0xf0" +@test repr("text/plain", reinterpret(UI8, 0x01)) == "::UI8 = 0x01" +@test repr("text/plain", reinterpret(UI8, 0xff)) == "::UI8 = 0xff" + # test block form @enum BritishFood begin blackpudding = 1 From 9c851b8b8f62c858168d9b1e79a001b273c30e8e Mon Sep 17 00:00:00 2001 From: Simeon Schaub Date: Mon, 19 Jul 2021 22:45:29 +0200 Subject: [PATCH 41/74] pretty-printing for ncat and nrow expressions (#41617) fixes #41134 (cherry picked from commit 2e08ccdb12cca46b109492b1198635759bae1e31) --- base/show.jl | 21 ++++++++++++++------- test/show.jl | 16 ++++++++++++++++ 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/base/show.jl b/base/show.jl index 79a2c1203f0d6..f3465a25d4abb 100644 --- a/base/show.jl +++ b/base/show.jl @@ -1303,6 +1303,7 @@ const expr_calls = Dict(:call => ('(',')'), :calldecl => ('(',')'), :ref => ('[',']'), :curly => ('{','}'), :(.) => ('(',')')) const expr_parens = Dict(:tuple=>('(',')'), :vcat=>('[',']'), :hcat =>('[',']'), :row =>('[',']'), :vect=>('[',']'), + :ncat =>('[',']'), :nrow =>('[',']'), :braces=>('{','}'), :bracescat=>('{','}')) ## AST decoding helpers ## @@ -1811,14 +1812,16 @@ function show_unquoted(io::IO, ex::Expr, indent::Int, prec::Int, quote_level::In # list-like forms, e.g. "[1, 2, 3]" elseif haskey(expr_parens, head) || # :vcat etc. - head === :typed_vcat || head === :typed_hcat + head === :typed_vcat || head === :typed_hcat || head === :typed_ncat # print the type and defer to the untyped case - if head === :typed_vcat || head === :typed_hcat + if head === :typed_vcat || head === :typed_hcat || head === :typed_ncat show_unquoted(io, args[1], indent, prec, quote_level) if head === :typed_vcat head = :vcat - else + elseif head === :typed_hcat head = :hcat + else + head = :ncat end args = args[2:end] nargs = nargs - 1 @@ -1828,15 +1831,19 @@ function show_unquoted(io::IO, ex::Expr, indent::Int, prec::Int, quote_level::In sep = "; " elseif head === :hcat || head === :row sep = " " + elseif head === :ncat || head === :nrow + sep = ";"^args[1] * " " + args = args[2:end] + nargs = nargs - 1 else sep = ", " end - head !== :row && print(io, op) + head !== :row && head !== :nrow && print(io, op) show_list(io, args, sep, indent, 0, quote_level) - if nargs == 1 && head === :vcat - print(io, ';') + if nargs <= 1 && (head === :vcat || head === :ncat) + print(io, sep[1:end-1]) end - head !== :row && print(io, cl) + head !== :row && head !== :nrow && print(io, cl) # transpose elseif (head === Symbol("'") && nargs == 1) || ( diff --git a/test/show.jl b/test/show.jl index e4bfd3f95af32..c00dcf523898c 100644 --- a/test/show.jl +++ b/test/show.jl @@ -2304,3 +2304,19 @@ end @test replstr([[1;;]]) == "1-element Vector{Matrix{$Int}}:\n [1;;]" @test replstr([[1;;;]]) == "1-element Vector{Array{$Int, 3}}:\n [1;;;]" end + +@testset "ncat and nrow" begin + @test_repr "[1;;]" + @test_repr "[1;;;]" + @test_repr "[1;; 2]" + @test_repr "[1;;; 2]" + @test_repr "[1;;; 2 3;;; 4]" + @test_repr "[1;;; 2;;;; 3;;; 4]" + + @test_repr "T[1;;]" + @test_repr "T[1;;;]" + @test_repr "T[1;; 2]" + @test_repr "T[1;;; 2]" + @test_repr "T[1;;; 2 3;;; 4]" + @test_repr "T[1;;; 2;;;; 3;;; 4]" +end From 765da54a4fad7f9fa51f7160ffa8d27efc4c90c3 Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Tue, 20 Jul 2021 09:21:52 +0200 Subject: [PATCH 42/74] make precompile files writable (#41614) (cherry picked from commit 6d58068541720a11eede10edfa24aae47ab2f5ab) --- base/loading.jl | 4 ++-- test/precompile.jl | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/base/loading.jl b/base/loading.jl index 851ebf17cc3b9..84ad47517cc31 100644 --- a/base/loading.jl +++ b/base/loading.jl @@ -1435,8 +1435,8 @@ function compilecache(pkg::PkgId, path::String, internal_stderr::IO = stderr, in open(tmppath, "a+") do f write(f, _crc32c(seekstart(f))) end - # inherit permission from the source file - chmod(tmppath, filemode(path) & 0o777) + # inherit permission from the source file (and make them writable) + chmod(tmppath, filemode(path) & 0o777 | 0o200) # Read preferences hash back from .ji file (we can't precompute because # we don't actually know what the list of compile-time preferences are without compiling) diff --git a/test/precompile.jl b/test/precompile.jl index f69e7a4766f2c..51b25b8325b2a 100644 --- a/test/precompile.jl +++ b/test/precompile.jl @@ -823,6 +823,10 @@ precompile_test_harness("Issue #25971") do load_path chmod(sourcefile, 0o600) cachefile = Base.compilecache(Base.PkgId("Foo25971")) @test filemode(sourcefile) == filemode(cachefile) + chmod(sourcefile, 0o444) + cachefile = Base.compilecache(Base.PkgId("Foo25971")) + # Check writable + @test touch(cachefile) == cachefile end precompile_test_harness("Issue #38312") do load_path From 77a5810faf2e73ed163e765ca7861e409ecd1cfd Mon Sep 17 00:00:00 2001 From: Fred Callaway Date: Tue, 20 Jul 2021 00:25:43 -0700 Subject: [PATCH 43/74] while loop -> for loop in _simplify_include_frames (fixes #41566) (#41622) * while loop -> for loop in _simplify_include_frames (fixes #41566) prevents the possibility of a bounds error when i = 0 (cherry picked from commit ed4f3169573903f1767871243375d2407db959a0) --- base/errorshow.jl | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/base/errorshow.jl b/base/errorshow.jl index 641cf5f2cdf4b..6cd94cbed371a 100644 --- a/base/errorshow.jl +++ b/base/errorshow.jl @@ -773,10 +773,9 @@ end # For improved user experience, filter out frames for include() implementation # - see #33065. See also #35371 for extended discussion of internal frames. function _simplify_include_frames(trace) - i = length(trace) - kept_frames = trues(i) + kept_frames = trues(length(trace)) first_ignored = nothing - while i >= 1 + for i in length(trace):-1:1 frame::StackFrame, _ = trace[i] mod = parentmodule(frame) if first_ignored === nothing @@ -798,10 +797,9 @@ function _simplify_include_frames(trace) first_ignored = nothing end end - i -= 1 end if first_ignored !== nothing - kept_frames[i:first_ignored] .= false + kept_frames[1:first_ignored] .= false end return trace[kept_frames] end From 1ddf23865009015452ae93719f4a119d2ea77b66 Mon Sep 17 00:00:00 2001 From: Dilum Aluthge Date: Tue, 20 Jul 2021 05:58:28 -0400 Subject: [PATCH 44/74] CI (Buildkite): move the `sanitizers` builders (e.g. `asan`) to the experimental pipeline (#41606) (cherry picked from commit c95448fb988441ecd7fb0604606ac08c5014abd3) --- .buildkite/experimental/0_webui.yml | 18 ++++++++++++++++++ .buildkite/experimental/pipeline.yml | 19 +++++++++++++++++++ .buildkite/{ => experimental}/sanitizers.yml | 10 +++++----- .buildkite/pipeline.yml | 1 - 4 files changed, 42 insertions(+), 6 deletions(-) create mode 100644 .buildkite/experimental/0_webui.yml create mode 100644 .buildkite/experimental/pipeline.yml rename .buildkite/{ => experimental}/sanitizers.yml (85%) diff --git a/.buildkite/experimental/0_webui.yml b/.buildkite/experimental/0_webui.yml new file mode 100644 index 0000000000000..ab3f68db4c393 --- /dev/null +++ b/.buildkite/experimental/0_webui.yml @@ -0,0 +1,18 @@ +# This file represents what is put into the webUI. +# It is purely for keeping track of the changes we make to the webUI configuration; modifying this file has no effect. +# We use the `cryptic` buildkite plugin to provide secrets management, which requires some integration into the WebUI's steps. +agents: + queue: "julia" + sandbox.jl: "true" + +steps: + - label: ":unlock: Unlock secrets, launch pipelines" + plugins: + - staticfloat/cryptic: + # Our list of pipelines that should be launched (but don't require a signature) + # These pipelines can be modified by any contributor and CI will still run. + # Build secrets will not be available in these pipelines (or their children) + # but some of our signed pipelines can wait upon the completion of these unsigned + # pipelines. + unsigned_pipelines: + - .buildkite/experimental/pipeline.yml diff --git a/.buildkite/experimental/pipeline.yml b/.buildkite/experimental/pipeline.yml new file mode 100644 index 0000000000000..6f86f7ef243e5 --- /dev/null +++ b/.buildkite/experimental/pipeline.yml @@ -0,0 +1,19 @@ +# This file launches all the build jobs that _don't_ require secrets access. +# These jobs can pass their output off to jobs that do require secrets access, +# but those privileged steps require signing before they can be run. +# +# Yes, this is creating another layer of indirection; the flow now looks like: +# +# [webui] -> pipeline.yml -> llvm_passes.yml +# +# when we could theoretically just have the `webui` launch `llvm_passes.yml`, +# however this raises the bar for contributors to add new (unsigned) steps to +# our CI configuration, so I'd rather live with an extra layer of indirection +# and only need to touch the webui configuration when we need to alter +# something about the privileged steps. +steps: + - label: ":buildkite: Launch unsigned pipelines" + commands: | + buildkite-agent pipeline upload .buildkite/experimental/sanitizers.yml + agents: + queue: julia diff --git a/.buildkite/sanitizers.yml b/.buildkite/experimental/sanitizers.yml similarity index 85% rename from .buildkite/sanitizers.yml rename to .buildkite/experimental/sanitizers.yml index f29ed4e42a4a6..534dac81e53f3 100644 --- a/.buildkite/sanitizers.yml +++ b/.buildkite/experimental/sanitizers.yml @@ -14,8 +14,8 @@ steps: - JuliaCI/julia#v1: version: 1.6 - staticfloat/sandbox#v1: - rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v1/llvm-passes.tar.gz - rootfs_treehash: "f3ed53f159e8f13edfba8b20ebdb8ece73c1b8a8" + rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v2.0/llvm_passes.tar.gz + rootfs_treehash: "0b5a80c1d0ab110a57fbdb7f4bc042a5ede310f3" uid: 1000 gid: 1000 workspaces: @@ -29,6 +29,6 @@ steps: echo "--- Test that ASAN is enabled" contrib/asan/check.jl ./tmp/test-asan/asan/usr/bin/julia-debug timeout_in_minutes: 120 - notify: - - github_commit_status: - context: "asan" + # notify: + # - github_commit_status: + # context: "asan" diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 99473055f2eeb..097b8976eea70 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -19,6 +19,5 @@ steps: buildkite-agent pipeline upload .buildkite/whitespace.yml buildkite-agent pipeline upload .buildkite/embedding.yml buildkite-agent pipeline upload .buildkite/llvm_passes.yml - buildkite-agent pipeline upload .buildkite/sanitizers.yml agents: queue: julia From 7142613f7f039aa6ddcb45610307c613ee77f24b Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Tue, 20 Jul 2021 13:59:55 +0200 Subject: [PATCH 45/74] [LLVM] Add missing GPU related patch (cherry picked from commit 8b15db7d659b40df6a7304df183fed61f49fb2c2) --- deps/llvm.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/deps/llvm.mk b/deps/llvm.mk index b6f6455f88255..c12c8c0eaa119 100644 --- a/deps/llvm.mk +++ b/deps/llvm.mk @@ -481,7 +481,7 @@ ifeq ($(LLVM_VER_PATCH), 0) $(eval $(call LLVM_PATCH,llvm-11-D85313-debuginfo-empty-arange)) # remove for LLVM 12 $(eval $(call LLVM_PATCH,llvm-11-D90722-rtdyld-absolute-relocs)) # remove for LLVM 12 endif # LLVM_VER 11.0.0 -$(eval $(call LLVM_PATCH,llvm-invalid-addrspacecast-sink)) # upstreamed as D92210 +$(eval $(call LLVM_PATCH,llvm-invalid-addrspacecast-sink)) # Still being upstreamed as D92210 $(eval $(call LLVM_PATCH,llvm-11-D92906-ppc-setjmp)) # remove for LLVM 12 $(eval $(call LLVM_PATCH,llvm-11-PR48458-X86ISelDAGToDAG)) # remove for LLVM 12 $(eval $(call LLVM_PATCH,llvm-11-D93092-ppc-knownbits)) # remove for LLVM 12 @@ -506,6 +506,7 @@ $(eval $(call LLVM_PATCH,llvm-julia-tsan-custom-as)) ifeq ($(BUILD_LLVM_CLANG),1) $(eval $(call LLVM_PATCH,llvm-D88630-clang-cmake)) endif +$(eval $(call LLVM_PATCH,llvm-invalid-addrspacecast-sink)) # Still being upstreamed as D92210 $(eval $(call LLVM_PATCH,llvm-11-D93154-globalisel-as)) $(eval $(call LLVM_PATCH,llvm-11-D94813-mergeicmps)) $(eval $(call LLVM_PROJ_PATCH,llvm-11-AArch64-FastIsel-bug)) From 117a31e606a7a87a6f6806c04511d66211e0d370 Mon Sep 17 00:00:00 2001 From: Sebastian Pfitzner Date: Tue, 20 Jul 2021 18:41:46 +0200 Subject: [PATCH 46/74] always send log messages to stderr by default (#41653) (cherry picked from commit e196b853c8950ce0d7863c9348fb01274de585d9) --- base/logging.jl | 2 +- stdlib/Logging/src/ConsoleLogger.jl | 2 +- test/corelogging.jl | 16 +--------------- 3 files changed, 3 insertions(+), 17 deletions(-) diff --git a/base/logging.jl b/base/logging.jl index fd35f547c82a6..8177d1eddff84 100644 --- a/base/logging.jl +++ b/base/logging.jl @@ -670,7 +670,7 @@ function handle_message(logger::SimpleLogger, level::LogLevel, message, _module, buf = IOBuffer() stream = logger.stream if !isopen(stream) - stream = level < Warn ? stdout : stderr + stream = stderr end iob = IOContext(buf, stream) levelstr = level == Warn ? "Warning" : string(level) diff --git a/stdlib/Logging/src/ConsoleLogger.jl b/stdlib/Logging/src/ConsoleLogger.jl index 04c56c6dbfaae..f13a8aa2f633b 100644 --- a/stdlib/Logging/src/ConsoleLogger.jl +++ b/stdlib/Logging/src/ConsoleLogger.jl @@ -119,7 +119,7 @@ function handle_message(logger::ConsoleLogger, level::LogLevel, message, _module msglines = [(indent=0, msg=l) for l in split(chomp(string(message)::String), '\n')] stream = logger.stream if !isopen(stream) - stream = level < Warn ? stdout : stderr + stream = stderr end dsize = displaysize(stream)::Tuple{Int,Int} nkwargs = length(kwargs)::Int diff --git a/test/corelogging.jl b/test/corelogging.jl index 698209661456b..9c5102d848013 100644 --- a/test/corelogging.jl +++ b/test/corelogging.jl @@ -341,20 +341,6 @@ end String(take!(io)) end - function genmsg_out(level, message, _module, filepath, line; kws...) - fname = tempname() - f = open(fname, "w") - logger = SimpleLogger() - redirect_stdout(f) do - handle_message(logger, level, message, _module, :group, :id, - filepath, line; kws...) - end - close(f) - buf = read(fname) - rm(fname) - String(buf) - end - function genmsg_err(level, message, _module, filepath, line; kws...) fname = tempname() f = open(fname, "w") @@ -370,7 +356,7 @@ end end # Simple - @test genmsg_out(Info, "msg", Main, "some/path.jl", 101) == + @test genmsg_err(Info, "msg", Main, "some/path.jl", 101) == """ ┌ Info: msg â”” @ Main some/path.jl:101 From 990283618723d00e4380556e86eccb4c636ae24e Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Tue, 20 Jul 2021 19:50:20 -0400 Subject: [PATCH 47/74] codegen: add missing return after error check (#41657) Fixes #41655 (cherry picked from commit 9442f1bf25d41feaaaa789b9d9a0dac344e60283) --- src/intrinsics.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/intrinsics.cpp b/src/intrinsics.cpp index 4096bba08d0c7..e1d821a34e42d 100644 --- a/src/intrinsics.cpp +++ b/src/intrinsics.cpp @@ -652,8 +652,10 @@ static jl_cgval_t emit_pointerset(jl_codectx_t &ctx, jl_cgval_t *argv) return emit_runtime_pointerset(ctx, argv); if (align.constant == NULL || !jl_is_long(align.constant)) return emit_runtime_pointerset(ctx, argv); - if (!is_valid_intrinsic_elptr(ety)) + if (!is_valid_intrinsic_elptr(ety)) { emit_error(ctx, "pointerset: invalid pointer type"); + return jl_cgval_t(); + } emit_typecheck(ctx, x, ety, "pointerset"); Value *idx = emit_unbox(ctx, T_size, i, (jl_value_t*)jl_long_type); From 95c8bb727bb647c729a6952e13806212b625ce20 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Tue, 20 Jul 2021 19:50:41 -0400 Subject: [PATCH 48/74] codegen: avoid attempting to box singleton objects unnecessarily (#41658) Fixes #41615 (cherry picked from commit b692c9b00f322276a2b7504e1a02295e7e27afc1) --- src/codegen.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index 9775db39892f7..acf7f1167cb14 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -946,11 +946,13 @@ static bool jl_is_pointerfree(jl_value_t* t) // these queries are usually related, but we split them out here // for convenience and clarity (and because it changes the calling convention) +// n.b. this must include jl_is_datatype_singleton (ghostType) and primitive types static bool deserves_stack(jl_value_t* t) { if (!jl_is_concrete_immutable(t)) return false; - return jl_datatype_isinlinealloc((jl_datatype_t*)t, 0); + jl_datatype_t *dt = (jl_datatype_t*)t; + return jl_is_datatype_singleton(dt) || jl_datatype_isinlinealloc(dt, 0); } static bool deserves_argbox(jl_value_t* t) { From a2ff7d70b026338fcc7bd5183b8293ac23752e6e Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Wed, 21 Jul 2021 12:15:12 -0400 Subject: [PATCH 49/74] fix memory corruption in `deleteat!` (#41646) n.b. `n == a->nrows + dec` Fixes https://github.com/JuliaData/DataFrames.jl/issues/2819 (cherry picked from commit 2e06a016fdad70736dd6c25c5a5286809e442b35) --- src/array.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/array.c b/src/array.c index 258b80948bf28..bc86eb50b95c5 100644 --- a/src/array.c +++ b/src/array.c @@ -1112,7 +1112,7 @@ STATIC_INLINE void jl_array_del_at_beg(jl_array_t *a, size_t idx, size_t dec, // Move the rest of the data if the offset changed if (newoffs != offset) { memmove_safe(a->flags.hasptr, newdata + nb1, olddata + nb1 + nbdec, nbtotal - nb1); - if (isbitsunion) memmove(newtypetagdata + idx, typetagdata + idx + dec, n - idx); + if (isbitsunion) memmove(newtypetagdata + idx, typetagdata + idx + dec, a->nrows - idx); } a->data = newdata; } From 1d6af37d891df781b70757d25936e1058f2424bc Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Wed, 21 Jul 2021 12:55:17 -0400 Subject: [PATCH 50/74] fix #41654, layout of 0-field structs with circular supertypes (#41660) (cherry picked from commit b3a99c00a0b4e75761b6d18a4e62a6ca76049a01) --- src/builtins.c | 4 ++-- test/core.jl | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/builtins.c b/src/builtins.c index 7ef93faaa6368..a6bcad48ab731 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -1557,9 +1557,9 @@ JL_CALLABLE(jl_f__typebody) // able to compute the layout of the object before needing to // publish it, so we must assume it cannot be inlined, if that // check passes, then we also still need to check the fields too. - if (!dt->name->mutabl && !references_name((jl_value_t*)dt->super, dt->name, 1)) { + if (!dt->name->mutabl && (nf == 0 || !references_name((jl_value_t*)dt->super, dt->name, 1))) { int mayinlinealloc = 1; - size_t i, nf = jl_svec_len(ft); + size_t i; for (i = 0; i < nf; i++) { jl_value_t *fld = jl_svecref(ft, i); if (references_name(fld, dt->name, 1)) { diff --git a/test/core.jl b/test/core.jl index 020722fd5f70b..e55705b3e6923 100644 --- a/test/core.jl +++ b/test/core.jl @@ -7234,6 +7234,12 @@ end @test string((B40050(),)) == "($B40050(),)" @test_broken isbitstype(Tuple{B40050}) +# issue #41654 +struct X41654 <: Ref{X41654} +end +@test isbitstype(X41654) +@test ('a'=>X41654(),)[1][2] isa X41654 + # Issue #34206/34207 function mre34206(a, n) va = view(a, :) From 7e46121303ac2efc1146358178c3bd05d7a8a28c Mon Sep 17 00:00:00 2001 From: Dilum Aluthge Date: Wed, 21 Jul 2021 13:10:03 -0400 Subject: [PATCH 51/74] CI: delete the `.buildkite/rootfs_images` directory (#41648) (cherry picked from commit 61b6994884642f8fc7e18844d37dc70b9dfdb9ab) --- .buildkite/rootfs_images/Manifest.toml | 134 ----------------------- .buildkite/rootfs_images/Project.toml | 5 - .buildkite/rootfs_images/README.md | 5 - .buildkite/rootfs_images/llvm-passes.jl | 31 ------ .buildkite/rootfs_images/rootfs_utils.jl | 123 --------------------- 5 files changed, 298 deletions(-) delete mode 100644 .buildkite/rootfs_images/Manifest.toml delete mode 100644 .buildkite/rootfs_images/Project.toml delete mode 100644 .buildkite/rootfs_images/README.md delete mode 100755 .buildkite/rootfs_images/llvm-passes.jl delete mode 100644 .buildkite/rootfs_images/rootfs_utils.jl diff --git a/.buildkite/rootfs_images/Manifest.toml b/.buildkite/rootfs_images/Manifest.toml deleted file mode 100644 index d24e9a4ee166e..0000000000000 --- a/.buildkite/rootfs_images/Manifest.toml +++ /dev/null @@ -1,134 +0,0 @@ -# This file is machine-generated - editing it directly is not advised - -[[ArgTools]] -uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" - -[[Artifacts]] -uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" - -[[Base64]] -uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" - -[[Dates]] -deps = ["Printf"] -uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" - -[[Downloads]] -deps = ["ArgTools", "LibCURL", "NetworkOptions"] -uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" - -[[InteractiveUtils]] -deps = ["Markdown"] -uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" - -[[JLLWrappers]] -deps = ["Preferences"] -git-tree-sha1 = "642a199af8b68253517b80bd3bfd17eb4e84df6e" -uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" -version = "1.3.0" - -[[LibCURL]] -deps = ["LibCURL_jll", "MozillaCACerts_jll"] -uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" - -[[LibCURL_jll]] -deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] -uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" - -[[LibGit2]] -deps = ["Base64", "NetworkOptions", "Printf", "SHA"] -uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" - -[[LibSSH2_jll]] -deps = ["Artifacts", "Libdl", "MbedTLS_jll"] -uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" - -[[Libdl]] -uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" - -[[Logging]] -uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" - -[[Markdown]] -deps = ["Base64"] -uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" - -[[MbedTLS_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" - -[[MozillaCACerts_jll]] -uuid = "14a3606d-f60d-562e-9121-12d972cd8159" - -[[NetworkOptions]] -uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" - -[[Pkg]] -deps = ["Artifacts", "Dates", "Downloads", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] -uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" - -[[Preferences]] -deps = ["TOML"] -git-tree-sha1 = "00cfd92944ca9c760982747e9a1d0d5d86ab1e5a" -uuid = "21216c6a-2e73-6563-6e65-726566657250" -version = "1.2.2" - -[[Printf]] -deps = ["Unicode"] -uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" - -[[REPL]] -deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] -uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" - -[[Random]] -deps = ["Serialization"] -uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" - -[[SHA]] -uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" - -[[Scratch]] -deps = ["Dates"] -git-tree-sha1 = "0b4b7f1393cff97c33891da2a0bf69c6ed241fda" -uuid = "6c6a2e73-6563-6170-7368-637461726353" -version = "1.1.0" - -[[Serialization]] -uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" - -[[Sockets]] -uuid = "6462fe0b-24de-5631-8697-dd941f90decc" - -[[TOML]] -deps = ["Dates"] -uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" - -[[Tar]] -deps = ["ArgTools", "SHA"] -uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" - -[[UUIDs]] -deps = ["Random", "SHA"] -uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" - -[[Unicode]] -uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" - -[[Zlib_jll]] -deps = ["Libdl"] -uuid = "83775a58-1f1d-513f-b197-d71354ab007a" - -[[ghr_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "f5c8cb306d4fe2d1fff90443a088fc5ba536c134" -uuid = "07c12ed4-43bc-5495-8a2a-d5838ef8d533" -version = "0.13.0+1" - -[[nghttp2_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" - -[[p7zip_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" diff --git a/.buildkite/rootfs_images/Project.toml b/.buildkite/rootfs_images/Project.toml deleted file mode 100644 index 1dbde5ed9df66..0000000000000 --- a/.buildkite/rootfs_images/Project.toml +++ /dev/null @@ -1,5 +0,0 @@ -[deps] -Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" -SHA = "ea8e919c-243c-51af-8825-aaa63cd721ce" -Scratch = "6c6a2e73-6563-6170-7368-637461726353" -ghr_jll = "07c12ed4-43bc-5495-8a2a-d5838ef8d533" diff --git a/.buildkite/rootfs_images/README.md b/.buildkite/rootfs_images/README.md deleted file mode 100644 index 1d3962c2bee3e..0000000000000 --- a/.buildkite/rootfs_images/README.md +++ /dev/null @@ -1,5 +0,0 @@ -## Rootfs images - -Our CI setup makes use of rootfs images that contain our build tools. -These rootfs images are built using the fairly simple scripts held within this directory. -Most images are based on Debian, making use of `debootstrap` to provide a quick and easy rootfs with packages installed through an initial `apt` invocation. diff --git a/.buildkite/rootfs_images/llvm-passes.jl b/.buildkite/rootfs_images/llvm-passes.jl deleted file mode 100755 index bc6d57eb2f87e..0000000000000 --- a/.buildkite/rootfs_images/llvm-passes.jl +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env julia - -## This rootfs includes enough of a host toolchain to build the LLVM passes. -## Eventually, this image will probably be replaced with the actual builder image, -## as that will have the necessary toolchains as well, but that image is not built yet. - -include("rootfs_utils.jl") - -const tag_name, force_overwrite = get_arguments(ARGS, @__FILE__) - -# Build debian-based image with the following extra packages: -packages = [ - "bash", - "build-essential", - "cmake", - "curl", - "gfortran", - "git", - "less", - "libatomic1", - "m4", - "perl", - "pkg-config", - "python", - "python3", - "wget", -] -tarball_path = debootstrap("llvm-passes"; packages) - -# Upload it -upload_rootfs_image(tarball_path; tag_name, force_overwrite) diff --git a/.buildkite/rootfs_images/rootfs_utils.jl b/.buildkite/rootfs_images/rootfs_utils.jl deleted file mode 100644 index 82baeec7a0933..0000000000000 --- a/.buildkite/rootfs_images/rootfs_utils.jl +++ /dev/null @@ -1,123 +0,0 @@ -#!/usr/bin/env julia - -# This is an example invocation of `debootstrap` to generate a Debian/Ubuntu-based rootfs -using Scratch, Pkg, Pkg.Artifacts, ghr_jll, SHA, Dates - -# Utility functions -getuid() = ccall(:getuid, Cint, ()) -getgid() = ccall(:getgid, Cint, ()) - -function debootstrap(name::String; release::String="buster", variant::String="minbase", - packages::Vector{String}=String[], force::Bool=false) - if Sys.which("debootstrap") === nothing - error("Must install `debootstrap`!") - end - - tarball_path = joinpath(@get_scratch!("rootfs-images"), "$(name).tar.gz") - if !force && isfile(tarball_path) - @error("Refusing to overwrite tarball without `force` set", tarball_path) - error() - end - - artifact_hash = create_artifact() do rootfs - packages_string = join(push!(packages, "locales"), ",") - @info("Running debootstrap", release, variant, packages) - run(`sudo debootstrap --variant=$(variant) --include=$(packages_string) $(release) "$(rootfs)"`) - - # Remove special `dev` files - @info("Cleaning up `/dev`") - for f in readdir(joinpath(rootfs, "dev"); join=true) - # Keep the symlinks around (such as `/dev/fd`), as they're useful - if !islink(f) - run(`sudo rm -rf "$(f)"`) - end - end - - # take ownership of the entire rootfs - @info("Chown'ing rootfs") - run(`sudo chown $(getuid()):$(getgid()) -R "$(rootfs)"`) - - # Write out rootfs-info to contain a minimally-identifying string - open(joinpath(rootfs, "etc", "rootfs-info"), write=true) do io - write(io, """ - rootfs_type=debootstrap - release=$(release) - variant=$(variant) - packages=$(packages_string) - build_date=$(Dates.now()) - """) - end - - # Write out a reasonable default resolv.conf - open(joinpath(rootfs, "etc", "resolv.conf"), write=true) do io - write(io, """ - nameserver 1.1.1.1 - nameserver 8.8.8.8 - """) - end - - # Remove `_apt` user so that `apt` doesn't try to `setgroups()` - @info("Removing `_apt` user") - open(joinpath(rootfs, "etc", "passwd"), write=true, read=true) do io - filtered_lines = filter(l -> !startswith(l, "_apt:"), readlines(io)) - truncate(io, 0) - seek(io, 0) - for l in filtered_lines - println(io, l) - end - end - - # Set up the one true locale - @info("Setting up UTF-8 locale") - open(joinpath(rootfs, "etc", "locale.gen"), "a") do io - println(io, "en_US.UTF-8 UTF-8") - end - run(`sudo chroot --userspec=$(getuid()):$(getgid()) $(rootfs) locale-gen`) - end - - # Archive it into a `.tar.gz` file - @info("Archiving", tarball_path, artifact_hash) - archive_artifact(artifact_hash, tarball_path) - - return tarball_path -end - -function upload_rootfs_image(tarball_path::String; - github_repo::String="JuliaCI/rootfs-images", - tag_name::String, - force_overwrite::Bool) - # Upload it to `github_repo` - tarball_url = "https://github.com/$(github_repo)/releases/download/$(tag_name)/$(basename(tarball_path))" - @info("Uploading to $(github_repo)@$(tag_name)", tarball_url) - cmd = ghr_jll.ghr() - append!(cmd.exec, ["-u", dirname(github_repo), "-r", basename(github_repo)]) - force_overwrite && push!(cmd.exec, "-replace") - append!(cmd.exec, [tag_name, tarball_path]) - run(cmd) - return tarball_url -end - -# process command-line arguments - -function get_arguments(args::AbstractVector, script_file::AbstractString) - usage = "Usage: $(basename(script_file)) [--force-overwrite]" - length(args) < 1 && throw(ArgumentError(usage)) - length(args) > 2 && throw(ArgumentError(usage)) - tag_name = get_tag_name(args; usage) - force_overwrite = get_force_overwrite(args; usage) - return (; tag_name, force_overwrite) -end - -function get_tag_name(args::AbstractVector; usage::AbstractString) - tag_name = convert(String, strip(args[1]))::String - isempty(tag_name) && throw(ArgumentError(usage)) - startswith(tag_name, "--") && throw(ArgumentError(usage)) - return tag_name -end - -function get_force_overwrite(args::AbstractVector; usage::AbstractString) - force_overwrite_string = strip(get(args, 2, "")) - force_overwrite_string == "" && return false - force_overwrite_string == "--force-overwrite" && return true - throw(ArgumentError(usage)) -end From 99c71aca24bf6608df1db2042f8a782376e80d72 Mon Sep 17 00:00:00 2001 From: Elliot Saba Date: Wed, 21 Jul 2021 20:27:25 -0700 Subject: [PATCH 52/74] [build] Automatically set `USE_BINARYBUILDER_CSL=0` when local CSL is new (#41645) We ship our own compiler support libraries to ensure a minimum level of support for BB-built libraries, however certain distros provide very bleeding-edge compilers. This can be a problem if we download an _older_ `libstdc++.so` and forcibly link against that when launching Julia, as when Julia itself is built with the local `g++`, it may use symbols that don't exist in the BB-sourced `libstdc++.so`. To address this, we default to not using BB-sourced CSLs if the `libstdc++.so` that the native compiler would use contains a symbol that our BB-sourced CSLs do not have. We use the monotonically-climbing `GLIBCXX_3.4.XX` version symbols for this purpose; encoding the "next" version number within `deps/csl.mk`, and triggering the BB-avoidance if that version exists within the system-provided `libstdc++.so`. (cherry picked from commit 27c0291f7fbecd811a3f9eb62b1159cff6b61e2a) --- Make.inc | 5 ++- deps/csl.mk | 40 ++++++++++++++++++- .../CompilerSupportLibraries_jll/Project.toml | 4 ++ 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/Make.inc b/Make.inc index 19c9629e0423e..5f8fcab2ede2c 100644 --- a/Make.inc +++ b/Make.inc @@ -1168,7 +1168,10 @@ BB_TRIPLET := $(subst $(SPACE),-,$(filter-out cxx%,$(filter-out libgfortran%,$(s LIBGFORTRAN_VERSION := $(subst libgfortran,,$(filter libgfortran%,$(subst -,$(SPACE),$(BB_TRIPLET_LIBGFORTRAN)))) # This is the set of projects that BinaryBuilder dependencies are hooked up for. -BB_PROJECTS := BLASTRAMPOLINE OPENBLAS LLVM LIBSUITESPARSE OPENLIBM GMP MBEDTLS LIBSSH2 NGHTTP2 MPFR CURL LIBGIT2 PCRE LIBUV LIBUNWIND DSFMT OBJCONV ZLIB P7ZIP CSL +# Note: we explicitly _do not_ define `CSL` here, since it requires some more +# advanced techniques to decide whether it should be installed from a BB source +# or not. See `deps/csl.mk` for more detail. +BB_PROJECTS := BLASTRAMPOLINE OPENBLAS LLVM LIBSUITESPARSE OPENLIBM GMP MBEDTLS LIBSSH2 NGHTTP2 MPFR CURL LIBGIT2 PCRE LIBUV LIBUNWIND DSFMT OBJCONV ZLIB P7ZIP define SET_BB_DEFAULT # First, check to see if BB is disabled on a global setting ifeq ($$(USE_BINARYBUILDER),0) diff --git a/deps/csl.mk b/deps/csl.mk index 423201cbb5a0c..9f95c00f3cfe7 100644 --- a/deps/csl.mk +++ b/deps/csl.mk @@ -1,5 +1,3 @@ -ifeq ($(USE_BINARYBUILDER_CSL),0) - # Interrogate the fortran compiler (which is always GCC based) on where it is keeping its libraries STD_LIB_PATH := $(shell LANG=C $(FC) -print-search-dirs | grep '^programs: =' | sed -e "s/^programs: =//") STD_LIB_PATH += :$(shell LANG=C $(FC) -print-search-dirs | grep '^libraries: =' | sed -e "s/^libraries: =//") @@ -12,6 +10,44 @@ define pathsearch $(firstword $(wildcard $(addsuffix /$(1),$(subst :, ,$(2))))) endef +# CSL bundles lots of system compiler libraries, and while it is quite bleeding-edge +# as compared to what most distros ship, if someone tries to build an older branch, +# the version of CSL that ships with that branch may become relatively old. This is +# not a problem for code that is built in BB, but when we build Julia with the system +# compiler, that compiler uses the version of `libstdc++` that it is bundled with, +# and we can get linker errors when trying to run that `julia` executable with the +# `libstdc++` that comes from the (now old) BB-built CSL. +# +# To fix this, we take note when the system `libstdc++.so` is newer than whatever we +# would get from CSL (by searching for a `GLIBCXX_3.4.X` symbol that does not exist +# in our CSL, but would in a newer one), and default to `USE_BINARYBUILDER_CSL=0` in +# this case. +CSL_NEXT_GLIBCXX_VERSION=GLIBCXX_3\.4\.30|GLIBCXX_3\.5\.|GLIBCXX_4\. + +# First, check to see if BB is disabled on a global setting +ifeq ($(USE_BINARYBUILDER),0) +USE_BINARYBUILDER_CSL ?= 0 +else +# If it's not, check to see if it's disabled by a USE_SYSTEM_xxx flag +ifeq ($(USE_SYSTEM_CSL),1) +USE_BINARYBUILDER_CSL ?= 0 +else +# If it's not, see if we should disable it due to `libstdc++` being newer: +LIBSTDCXX_PATH := $(eval $(call pathsearch,libstdc++,$(STD_LIB_PATH))) +ifneq (,$(and $(LIBSTDCXX_PATH),$(shell objdump -p $(LIBSTDCXX_PATH) | grep $(CSL_NEXT_GLIBCXX_VERSION)))) +# Found `libstdc++`, grepped it for strings and found a `GLIBCXX` symbol +# that is newer that whatever we have in CSL. Default to not using BB. +USE_BINARYBUILDER_CSL ?= 0 +else +# Either we didn't find `libstdc++` (e.g. we're using `clang`), or we +# found it and couldn't find the new symbol in it (it's older than what +# BB provides, so let's use BB instead) +USE_BINARYBUILDER_CSL ?= 1 +endif +endif +endif + +ifeq ($(USE_BINARYBUILDER_CSL),0) define copy_csl install-csl: | $$(build_shlibdir) $$(build_shlibdir)/$(1) $$(build_shlibdir)/$(1): | $$(build_shlibdir) diff --git a/stdlib/CompilerSupportLibraries_jll/Project.toml b/stdlib/CompilerSupportLibraries_jll/Project.toml index ac78369b12602..b76517c828d0e 100644 --- a/stdlib/CompilerSupportLibraries_jll/Project.toml +++ b/stdlib/CompilerSupportLibraries_jll/Project.toml @@ -1,5 +1,9 @@ name = "CompilerSupportLibraries_jll" uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" + +# NOTE: When updating this, also make sure to update the value +# `CSL_NEXT_GLIBCXX_VERSION` in `deps/csl.mk`, to properly disable +# automatic usage of BB-built CSLs on extremely up-to-date systems! version = "0.5.0+0" [deps] From b2d80a1420b98835fec812e9c1e0859dad8433eb Mon Sep 17 00:00:00 2001 From: Martin Holters Date: Thu, 22 Jul 2021 07:41:31 +0200 Subject: [PATCH 53/74] Fix `fieldtype_tfunc` for union types (#41667) Co-authored-by: Jameson Nash (cherry picked from commit 2c02de80bd7ec2e33378e75be34635c072d06a60) --- base/compiler/tfuncs.jl | 15 +++++++++++++-- test/compiler/inference.jl | 11 +++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/base/compiler/tfuncs.jl b/base/compiler/tfuncs.jl index 57b86bf504217..c31b32428a297 100644 --- a/base/compiler/tfuncs.jl +++ b/base/compiler/tfuncs.jl @@ -1015,8 +1015,19 @@ function _fieldtype_tfunc(@nospecialize(s), exact::Bool, @nospecialize(name)) exact = exact && !has_free_typevars(s) u = unwrap_unionall(s) if isa(u, Union) - return tmerge(_fieldtype_tfunc(rewrap(u.a, s), exact, name), - _fieldtype_tfunc(rewrap(u.b, s), exact, name)) + ta0 = _fieldtype_tfunc(rewrap(u.a, s), exact, name) + tb0 = _fieldtype_tfunc(rewrap(u.b, s), exact, name) + ta0 ⊑ tb0 && return tb0 + tb0 ⊑ ta0 && return ta0 + ta, exacta, _, istypea = instanceof_tfunc(ta0) + tb, exactb, _, istypeb = instanceof_tfunc(tb0) + if exact && exacta && exactb + return Const(Union{ta, tb}) + end + if istypea && istypeb + return Type{<:Union{ta, tb}} + end + return Any end u isa DataType || return Any if isabstracttype(u) diff --git a/test/compiler/inference.jl b/test/compiler/inference.jl index 008e6ff0d6997..4d7aed372f6c8 100644 --- a/test/compiler/inference.jl +++ b/test/compiler/inference.jl @@ -3395,3 +3395,14 @@ end x.x end) == Any[Int] end + +@testset "fieldtype for unions" begin # e.g. issue #40177 + f40177(::Type{T}) where {T} = fieldtype(T, 1) + for T in [ + Union{Tuple{Val}, Tuple{Tuple}}, + Union{Base.RefValue{T}, Type{Int32}} where T<:Real, + Union{Tuple{Vararg{Symbol}}, Tuple{Float64, Vararg{Float32}}}, + ] + @test @inferred(f40177(T)) == fieldtype(T, 1) + end +end From e5267faa1e9bbaac7178e6be185e96cf18850b81 Mon Sep 17 00:00:00 2001 From: Dilum Aluthge Date: Thu, 22 Jul 2021 20:21:27 -0400 Subject: [PATCH 54/74] Update the `file.jl` tests to allow for both `EPERM` and `EINVAL` in the non-root CHOWN tests (#41682) Co-authored-by: Elliot Saba Co-authored-by: Elliot Saba (cherry picked from commit 114ee174cff04b7ecf3514d58e310384fa1bbf17) --- test/file.jl | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/test/file.jl b/test/file.jl index 6c48cedb0ebb0..b6db735e7c483 100644 --- a/test/file.jl +++ b/test/file.jl @@ -491,6 +491,29 @@ rm(c_tmpdir, recursive=true) @test_throws Base._UVError("unlink($(repr(c_tmpdir)))", Base.UV_ENOENT) rm(c_tmpdir, recursive=true) @test rm(c_tmpdir, force=true, recursive=true) === nothing +# Some operations can return multiple different error codes depending on the system environment. +function throws_matching_exception(f::Function, acceptable_exceptions::AbstractVector) + try + f() + @error "No exception was thrown." + return false + catch ex + if ex in acceptable_exceptions + return true + else + @error "The thrown exception is not in the list of acceptable exceptions" acceptable_exceptions exception=(ex, catch_backtrace()) + return false + end + end +end +function throws_matching_uv_error(f::Function, pfx::AbstractString, codes::AbstractVector{<:Integer}) + acceptable_exceptions = multiple_uv_errors(pfx, codes) + return throws_matching_exception(f, acceptable_exceptions) +end +function multiple_uv_errors(pfx::AbstractString, codes::AbstractVector{<:Integer}) + return [Base._UVError(pfx, code) for code in codes] +end + if !Sys.iswindows() # chown will give an error if the user does not have permissions to change files if get(ENV, "USER", "") == "root" || get(ENV, "HOME", "") == "/root" @@ -503,8 +526,12 @@ if !Sys.iswindows() @test stat(file).gid == 0 @test stat(file).uid == 0 else - @test_throws Base._UVError("chown($(repr(file)), -2, -1)", Base.UV_EPERM) chown(file, -2, -1) # Non-root user cannot change ownership to another user - @test_throws Base._UVError("chown($(repr(file)), -1, -2)", Base.UV_EPERM) chown(file, -1, -2) # Non-root user cannot change group to a group they are not a member of (eg: nogroup) + @test throws_matching_uv_error("chown($(repr(file)), -2, -1)", [Base.UV_EPERM, Base.UV_EINVAL]) do + chown(file, -2, -1) # Non-root user cannot change ownership to another user + end + @test throws_matching_uv_error("chown($(repr(file)), -1, -2)", [Base.UV_EPERM, Base.UV_EINVAL]) do + chown(file, -1, -2) # Non-root user cannot change group to a group they are not a member of (eg: nogroup) + end end else # test that chown doesn't cause any errors for Windows From f7aaf22f404cf7ad68a8cd33a8b81809d3c30aa6 Mon Sep 17 00:00:00 2001 From: Dilum Aluthge Date: Sat, 24 Jul 2021 22:58:54 -0400 Subject: [PATCH 55/74] CI (Buildkite): Add the `package_linux64` and `doctest` builders (#41541) Co-authored-by: Elliot Saba (cherry picked from commit c7097c5793545658aef20d6bb83eb1af7bc81310) --- .buildkite/misc/doctest.yml | 39 +++++ .buildkite/{ => misc}/embedding.yml | 4 +- .../{llvm_passes.yml => misc/llvmpasses.yml} | 8 +- .buildkite/{ => misc}/whitespace.yml | 4 +- .buildkite/pipeline.yml | 19 ++- .buildkite/platforms/linux64.yml | 80 +++++++++++ .buildkite/rr_capture.jl | 134 ++++++++++++++++++ 7 files changed, 273 insertions(+), 15 deletions(-) create mode 100644 .buildkite/misc/doctest.yml rename .buildkite/{ => misc}/embedding.yml (91%) rename .buildkite/{llvm_passes.yml => misc/llvmpasses.yml} (88%) rename .buildkite/{ => misc}/whitespace.yml (87%) create mode 100644 .buildkite/platforms/linux64.yml create mode 100644 .buildkite/rr_capture.jl diff --git a/.buildkite/misc/doctest.yml b/.buildkite/misc/doctest.yml new file mode 100644 index 0000000000000..234e49f5dcf53 --- /dev/null +++ b/.buildkite/misc/doctest.yml @@ -0,0 +1,39 @@ +# These steps should only run on `sandbox.jl` machines, not `docker`-isolated ones +# since we need nestable sandboxing. The rootfs images being used here are built from +# the `.buildkite/rootfs_images/llvm-passes.jl` file. +agents: + queue: "julia" + # Only run on `sandbox.jl` machines (not `docker`-isolated ones) since we need nestable sandboxing + sandbox.jl: "true" + os: "linux" + +steps: + - label: "doctest" + key: doctest + plugins: + - JuliaCI/julia#v1: + version: 1.6 + - staticfloat/sandbox#v1: + rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v3.0/package_linux.x86_64.tar.gz + rootfs_treehash: "d5722d586b93eb307bb6340d275afdbf7578a756" + uid: 1000 + gid: 1000 + workspaces: + # Include `/cache/repos` so that our `git` version introspection works. + - "/cache/repos:/cache/repos" + commands: | + echo "--- Build Julia from source" + make -j 6 + + echo "--- Print Julia version info" + ./julia -e 'using InteractiveUtils; InteractiveUtils.versioninfo()' + + echo "--- Build Julia docs" + make docs + + echo "--- Run Julia doctests" + JULIA_NUM_THREADS=1 make -C doc doctest=true + timeout_in_minutes: 120 + notify: + - github_commit_status: + context: "doctest" diff --git a/.buildkite/embedding.yml b/.buildkite/misc/embedding.yml similarity index 91% rename from .buildkite/embedding.yml rename to .buildkite/misc/embedding.yml index 5cf6b985573f5..31f85633479a4 100644 --- a/.buildkite/embedding.yml +++ b/.buildkite/misc/embedding.yml @@ -14,8 +14,8 @@ steps: - JuliaCI/julia#v1: version: 1.6 - staticfloat/sandbox#v1: - rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v1/llvm-passes.tar.gz - rootfs_treehash: "f3ed53f159e8f13edfba8b20ebdb8ece73c1b8a8" + rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v3.0/package_linux.x86_64.tar.gz + rootfs_treehash: "d5722d586b93eb307bb6340d275afdbf7578a756" uid: 1000 gid: 1000 workspaces: diff --git a/.buildkite/llvm_passes.yml b/.buildkite/misc/llvmpasses.yml similarity index 88% rename from .buildkite/llvm_passes.yml rename to .buildkite/misc/llvmpasses.yml index 7453af82c1e73..7660b3978e967 100644 --- a/.buildkite/llvm_passes.yml +++ b/.buildkite/misc/llvmpasses.yml @@ -14,8 +14,8 @@ steps: - JuliaCI/julia#v1: version: 1.6 - staticfloat/sandbox#v1: - rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v1/llvm-passes.tar.gz - rootfs_treehash: "f3ed53f159e8f13edfba8b20ebdb8ece73c1b8a8" + rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v3.1/llvm_passes.x86_64.tar.gz + rootfs_treehash: "9dd715500b117a16fcfa419ea0bca0c0ca902cee" workspaces: # Include `/cache/repos` so that our `git` version introspection works. - "/cache/repos:/cache/repos" @@ -36,8 +36,8 @@ steps: - JuliaCI/julia#v1: version: 1.6 - staticfloat/sandbox#v1: - rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v1/llvm-passes.tar.gz - rootfs_treehash: "f3ed53f159e8f13edfba8b20ebdb8ece73c1b8a8" + rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v3.0/package_linux.x86_64.tar.gz + rootfs_treehash: "d5722d586b93eb307bb6340d275afdbf7578a756" uid: 1000 gid: 1000 workspaces: diff --git a/.buildkite/whitespace.yml b/.buildkite/misc/whitespace.yml similarity index 87% rename from .buildkite/whitespace.yml rename to .buildkite/misc/whitespace.yml index bd625e855c5b5..01b4c79e7822b 100644 --- a/.buildkite/whitespace.yml +++ b/.buildkite/misc/whitespace.yml @@ -14,8 +14,8 @@ steps: - JuliaCI/julia#v1: version: 1.6 - staticfloat/sandbox#v1: - rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v1/llvm-passes.tar.gz - rootfs_treehash: "f3ed53f159e8f13edfba8b20ebdb8ece73c1b8a8" + rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v3.0/package_linux.x86_64.tar.gz + rootfs_treehash: "d5722d586b93eb307bb6340d275afdbf7578a756" workspaces: - "/cache/repos:/cache/repos" commands: | diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 097b8976eea70..3a3ebc718cbaa 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -4,9 +4,9 @@ # # Yes, this is creating another layer of indirection; the flow now looks like: # -# [webui] -> pipeline.yml -> llvm_passes.yml +# [webui] -> pipeline.yml -> misc/whitespace.yml # -# when we could theoretically just have the `webui` launch `llvm_passes.yml`, +# when we could theoretically just have the `webui` launch `misc/whitespace.yml`, # however this raises the bar for contributors to add new (unsigned) steps to # our CI configuration, so I'd rather live with an extra layer of indirection # and only need to touch the webui configuration when we need to alter @@ -14,10 +14,15 @@ steps: - label: ":buildkite: Launch unsigned pipelines" commands: | - # We launch whitespace first, because we want that pipeline to finish as quickly as possible. - # The remaining unsigned pipelines are launched in alphabetical order. - buildkite-agent pipeline upload .buildkite/whitespace.yml - buildkite-agent pipeline upload .buildkite/embedding.yml - buildkite-agent pipeline upload .buildkite/llvm_passes.yml + # First, we launch whitespace, because we want that pipeline to finish as quickly as possible. + buildkite-agent pipeline upload .buildkite/misc/whitespace.yml + + # Next, we launch the miscellaneous pipelines in alphabetical order. + buildkite-agent pipeline upload .buildkite/misc/doctest.yml + buildkite-agent pipeline upload .buildkite/misc/embedding.yml + buildkite-agent pipeline upload .buildkite/misc/llvmpasses.yml + + # Finally, we launch the platform pipelines in alphabetical order. + buildkite-agent pipeline upload .buildkite/platforms/linux64.yml agents: queue: julia diff --git a/.buildkite/platforms/linux64.yml b/.buildkite/platforms/linux64.yml new file mode 100644 index 0000000000000..69befe1064df7 --- /dev/null +++ b/.buildkite/platforms/linux64.yml @@ -0,0 +1,80 @@ +# These steps should only run on `sandbox.jl` machines, not `docker`-isolated ones +# since we need nestable sandboxing. The rootfs images being used here are built from +# the `.buildkite/rootfs_images/llvm-passes.jl` file. +agents: + queue: "julia" + # Only run on `sandbox.jl` machines (not `docker`-isolated ones) since we need nestable sandboxing + sandbox.jl: "true" + os: "linux" + +steps: + - label: "package_linux64" + key: package_linux64 + plugins: + - JuliaCI/julia#v1: + version: 1.6 + - staticfloat/sandbox#v1: + rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v3.0/package_linux.x86_64.tar.gz + rootfs_treehash: "d5722d586b93eb307bb6340d275afdbf7578a756" + uid: 1000 + gid: 1000 + workspaces: + # Include `/cache/repos` so that our `git` version introspection works. + - "/cache/repos:/cache/repos" + commands: | + echo "--- Build Julia from source" + make -j 6 + make release + make install + + echo "--- Print Julia version info" + ./julia -e 'using InteractiveUtils; InteractiveUtils.versioninfo()' + + echo "--- Compress build artifacts" + mv julia-* julia-artifact + rm -rf julia-linux64.tar.gz + tar czf julia-linux64.tar.gz julia-artifact/ + + echo "--- Upload build artifacts" + buildkite-agent artifact upload julia-linux64.tar.gz + timeout_in_minutes: 60 + notify: + - github_commit_status: + context: "package_linux64" + + # - label: "tester_linux64" + # key: tester_linux64 + # depends_on: package_linux64 + # plugins: + # - JuliaCI/julia#v1: + # version: 1.6 + # - staticfloat/sandbox#v1: + # # TODO: use a separate `tester_linux` image, instead of using the `package_linux` image. + # rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v3.0/package_linux.x86_64.tar.gz + # rootfs_treehash: "d5722d586b93eb307bb6340d275afdbf7578a756" + # uid: 1000 + # gid: 1000 + # workspaces: + # # Include `/cache/repos` so that our `git` version introspection works. + # - "/cache/repos:/cache/repos" + # env: + # JULIA_SHELL: "/bin/bash" + # commands: | + # echo "--- Download build artifacts" + # rm -rf julia-linux64.tar.gz + # buildkite-agent artifact download julia-linux64.tar.gz . + # + # echo "--- Extract build artifacts" + # rm -rf julia-artifact/ + # tar xzf julia-linux64.tar.gz julia-artifact/ + # + # echo "--- Print Julia version info" + # julia-artifact/bin/julia -e 'using InteractiveUtils; InteractiveUtils.versioninfo()' + # + # echo "--- Run the Julia test suite" + # unset JULIA_DEPOT_PATH + # julia-artifact/bin/julia .buildkite/rr_capture.jl julia-artifact/bin/julia -e 'Base.runtests(["all"]; ncores = Sys.CPU_THREADS)' + # timeout_in_minutes: 120 + # notify: + # - github_commit_status: + # context: "tester_linux64" diff --git a/.buildkite/rr_capture.jl b/.buildkite/rr_capture.jl new file mode 100644 index 0000000000000..07d57f31ff29c --- /dev/null +++ b/.buildkite/rr_capture.jl @@ -0,0 +1,134 @@ +using Dates +using Pkg +using Tar + +if Base.VERSION < v"1.6" + throw(ErrorException("The `rr_capture.jl` script requires Julia 1.6 or greater")) +end + +if length(ARGS) < 1 + throw(ErrorException("Usage: rr_capture.jl [command...]")) +end + +const TIMEOUT = 2 * 60 * 60 # timeout in seconds + +# We only use `rr` on the `tester_linux64` builder +const use_rr_if_builder_is = "tester_linux64" + +const run_id = get(ENV, "BUILDKITE_JOB_ID", "unknown") +const shortcommit = get(ENV, "BUILDKITE_COMMIT", "unknown") +const builder = get(ENV, "BUILDKITE_STEP_KEY", use_rr_if_builder_is) +const use_rr = builder == use_rr_if_builder_is + +@info "" run_id shortcommit builder use_rr +@info "" ARGS + +# if !use_rr # TODO: uncomment this line +if true # TODO: delete this line + @info "We will not run the tests under rr" + p = run(`$ARGS`) + exit(p.exitcode) +end + +@info "We will run the tests under rr" + +const num_cores = min(Sys.CPU_THREADS, 8, parse(Int, get(ENV, "JULIA_TEST_NUM_CORES", "8")) + 1) +@info "" num_cores + +proc = nothing + +new_env = copy(ENV) +mktempdir() do dir + Pkg.activate(dir) + Pkg.add("rr_jll") + Pkg.add("Zstd_jll") + + rr_jll = Base.require(Base.PkgId(Base.UUID((0xe86bdf43_55f7_5ea2_9fd0_e7daa2c0f2b4)), "rr_jll")) + zstd_jll = Base.require(Base.PkgId(Base.UUID((0x3161d3a3_bdf6_5164_811a_617609db77b4)), "Zstd_jll")) + rr(func) = Base.invokelatest(rr_jll.rr, func; adjust_LIBPATH=false) + rr() do rr_path + capture_script_path = joinpath(dir, "capture_output.sh") + loader = Sys.WORD_SIZE == 64 ? "/lib64/ld-linux-x86-64.so.2" : "/lib/ld-linux.so.2" + open(capture_script_path, "w") do io + write(io, """ + #!/bin/bash + + $(rr_path) record --nested=detach "\$@" > >(tee -a $(dir)/stdout.log) 2> >(tee -a $(dir)/stderr.log >&2) + """) + end + chmod(capture_script_path, 0o755) + + new_env = copy(ENV) + new_env["_RR_TRACE_DIR"] = joinpath(dir, "rr_traces") + new_env["RR_LOG"]="all:debug" + new_env["RR_LOG_BUFFER"]="100000" + new_env["JULIA_RR"] = capture_script_path + t_start = time() + global proc = run(setenv(`$(rr_path) record --num-cores=$(num_cores) $ARGS`, new_env), (stdin, stdout, stderr); wait=false) + + # Start asynchronous timer that will kill `rr` + @async begin + sleep(TIMEOUT) + + # If we've exceeded the timeout and `rr` is still running, kill it. + if isopen(proc) + println(stderr, "\n\nProcess timed out. Signalling `rr` for force-cleanup!") + kill(proc, Base.SIGTERM) + + # Give `rr` a chance to cleanup + sleep(60) + + if isopen(proc) + println(stderr, "\n\n`rr` failed to cleanup within one minute, killing and exiting immediately!") + kill(proc, Base.SIGKILL) + exit(1) + end + end + end + + # Wait for `rr` to finish, either through naturally finishing its run, or `SIGTERM`. + # If we have to `SIGKILL` + wait(proc) + + # On a non-zero exit code, upload the `rr` trace + if !success(proc) + println(stderr, "`rr` returned $(proc.exitcode), packing and uploading traces...") + + if !isdir(joinpath(dir, "rr_traces")) + println(stderr, "No `rr_traces` directory! Did `rr` itself fail?") + exit(1) + end + + # Clean up non-traces + rm(joinpath(dir, "rr_traces", "latest-trace")) + rm(joinpath(dir, "rr_traces", "cpu_lock")) + + # Create a directory for the pack files to go + pack_dir = joinpath(dir, "pack") + mkdir(pack_dir) + + # Pack all traces + trace_dirs = [joinpath(dir, "rr_traces", f) for f in readdir(joinpath(dir, "rr_traces"))] + filter!(isdir, trace_dirs) + run(ignorestatus(`$(rr_path) pack --pack-dir=$pack_dir $(trace_dirs)`)) + + # Tar it up + mkpath("dumps") + datestr = Dates.format(now(), dateformat"yyyy-mm-dd_HH_MM_SS") + dst_path = "dumps/rr-run_$(run_id)-gitsha_$(shortcommit)-$(datestr).tar.zst" + zstd_jll.zstdmt() do zstdp + tarproc = open(`$zstdp -o $dst_path`, "w") + Tar.create(dir, tarproc) + close(tarproc.in) + end + end + end +end + +# Pass the exit code back up to Buildkite +if proc.termsignal != 0 + ccall(:raise, Cvoid, (Cint,), proc.termsignal) + exit(1) # Just in case the signal did not cause an exit +else + exit(proc.exitcode) +end From 6806bf2d80e9e1fd90f25478fa84a9c76091ec65 Mon Sep 17 00:00:00 2001 From: Dilum Aluthge Date: Sun, 25 Jul 2021 05:16:24 -0400 Subject: [PATCH 56/74] CI (Buildkite): Update all rootfs images to version v3.1, add some documentation, and reorganize/rename/move a bunch of configuration files (#41698) (cherry picked from commit e6e79f7ab4549ab4d6ffbad22038ebfce1368f93) --- .buildkite/README.md | 5 ++ .buildkite/coverage-linux64/0_webui.yml | 16 ------ .buildkite/coverage-linux64/README.md | 6 --- .buildkite/coverage-linux64/pipeline.yml | 53 ------------------- .../coverage-linux64/run_tests_parallel.jl | 36 ------------- .../coverage-linux64/run_tests_serial.jl | 16 ------ .buildkite/experimental/pipeline.yml | 19 ------- .buildkite/pipeline.yml | 28 ---------- .../{ => pipelines}/experimental/0_webui.yml | 8 ++- .buildkite/pipelines/experimental/README.md | 7 +++ .../experimental/launch_unsigned_builders.yml | 6 +++ .../experimental/misc}/sanitizers.yml | 13 ++--- .buildkite/{ => pipelines/main}/0_webui.yml | 4 +- .buildkite/pipelines/main/README.md | 15 ++++++ .../main/launch_unsigned_builders.yml | 29 ++++++++++ .../{ => pipelines/main}/misc/doctest.yml | 9 ++-- .../{ => pipelines/main}/misc/embedding.yml | 7 +-- .../{ => pipelines/main}/misc/llvmpasses.yml | 7 +-- .../main/misc}/signed_pipeline_test.yml | 0 .../{ => pipelines/main}/misc/whitespace.yml | 7 +-- .../main}/platforms/linux64.yml | 14 +++-- .buildkite/pipelines/scheduled/0_webui.yml | 24 +++++++++ .buildkite/pipelines/scheduled/README.md | 5 ++ .../scheduled/coverage/coverage_linux64.yml | 40 ++++++++++++++ .../scheduled/coverage/run_tests_parallel.jl | 25 +++++++++ .../scheduled/coverage}/upload_coverage.jl | 0 .../scheduled/launch_unsigned_builders.yml | 0 .buildkite/{ => utilities/rr}/rr_capture.jl | 0 28 files changed, 185 insertions(+), 214 deletions(-) create mode 100644 .buildkite/README.md delete mode 100644 .buildkite/coverage-linux64/0_webui.yml delete mode 100644 .buildkite/coverage-linux64/README.md delete mode 100644 .buildkite/coverage-linux64/pipeline.yml delete mode 100644 .buildkite/coverage-linux64/run_tests_parallel.jl delete mode 100644 .buildkite/coverage-linux64/run_tests_serial.jl delete mode 100644 .buildkite/experimental/pipeline.yml delete mode 100644 .buildkite/pipeline.yml rename .buildkite/{ => pipelines}/experimental/0_webui.yml (67%) create mode 100644 .buildkite/pipelines/experimental/README.md create mode 100644 .buildkite/pipelines/experimental/launch_unsigned_builders.yml rename .buildkite/{experimental => pipelines/experimental/misc}/sanitizers.yml (67%) rename .buildkite/{ => pipelines/main}/0_webui.yml (89%) create mode 100644 .buildkite/pipelines/main/README.md create mode 100644 .buildkite/pipelines/main/launch_unsigned_builders.yml rename .buildkite/{ => pipelines/main}/misc/doctest.yml (71%) rename .buildkite/{ => pipelines/main}/misc/embedding.yml (76%) rename .buildkite/{ => pipelines/main}/misc/llvmpasses.yml (83%) rename .buildkite/{ => pipelines/main/misc}/signed_pipeline_test.yml (100%) rename .buildkite/{ => pipelines/main}/misc/whitespace.yml (63%) rename .buildkite/{ => pipelines/main}/platforms/linux64.yml (79%) create mode 100644 .buildkite/pipelines/scheduled/0_webui.yml create mode 100644 .buildkite/pipelines/scheduled/README.md create mode 100644 .buildkite/pipelines/scheduled/coverage/coverage_linux64.yml create mode 100644 .buildkite/pipelines/scheduled/coverage/run_tests_parallel.jl rename .buildkite/{coverage-linux64 => pipelines/scheduled/coverage}/upload_coverage.jl (100%) create mode 100644 .buildkite/pipelines/scheduled/launch_unsigned_builders.yml rename .buildkite/{ => utilities/rr}/rr_capture.jl (100%) diff --git a/.buildkite/README.md b/.buildkite/README.md new file mode 100644 index 0000000000000..12887536b90c1 --- /dev/null +++ b/.buildkite/README.md @@ -0,0 +1,5 @@ +# Buildkite + +This directory contains the Buildkite configuration files for Base Julia CI. + +The rootfs image definitions are located in the [rootfs-images](https://github.com/JuliaCI/rootfs-images) repository. diff --git a/.buildkite/coverage-linux64/0_webui.yml b/.buildkite/coverage-linux64/0_webui.yml deleted file mode 100644 index b0df8ec41de68..0000000000000 --- a/.buildkite/coverage-linux64/0_webui.yml +++ /dev/null @@ -1,16 +0,0 @@ -# This file represents what is put into the webUI. -# It is purely for keeping track of the changes we make to the webUI configuration; modifying this file has no effect. -# We use the `cryptic` buildkite plugin to provide secrets management, which requires some integration into the WebUI's steps. -agents: - queue: "julia" - sandbox.jl: "true" - -steps: - - label: ":unlock: Unlock secrets, launch pipelines" - plugins: - - staticfloat/cryptic: - # Our signed pipelines must have a `signature` or `signature_file` parameter that - # verifies the treehash of the pipeline itself and the inputs listed in `inputs` - signed_pipelines: - - pipeline: .buildkite/coverage-linux64/pipeline.yml - signature: U2FsdGVkX190BiaBGCTT6GNBDe5cHX3ZAP0IXbBfOWo7ys+1IuD5ymf4ImJbRIeE8NQac+iqud+bqCPHjii6DKmqzX+Jz6vax1NY3AxROhYlO5spUClvKr1wdngUCQON diff --git a/.buildkite/coverage-linux64/README.md b/.buildkite/coverage-linux64/README.md deleted file mode 100644 index 8cfb31d698225..0000000000000 --- a/.buildkite/coverage-linux64/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# Coverage pipeline - -We run coverage on a separate pipeline, that uses a scheduled build rather than webhooks. -The pipeline is here: https://buildkite.com/julialang/julia-coverage-linux64 - -It contains [its own webui steps](0_webuiy.ml) (listed here in this repository for clarity) and its own [pipeline.yml](pipeline.yml). diff --git a/.buildkite/coverage-linux64/pipeline.yml b/.buildkite/coverage-linux64/pipeline.yml deleted file mode 100644 index 218212d24ac2a..0000000000000 --- a/.buildkite/coverage-linux64/pipeline.yml +++ /dev/null @@ -1,53 +0,0 @@ -# These steps should only run on `sandbox.jl` machines, not `docker`-isolated ones -# since we need nestable sandboxing. The rootfs images being used here are built from -# the `.buildkite/rootfs_images/llvm-passes.jl` file. -agents: - queue: "julia" - # Only run on `sandbox.jl` machines (not `docker`-isolated ones) since we need nestable sandboxing - sandbox.jl: "true" - os: "linux" - -steps: - - label: ":unlock: :coverage: Run coverage test" - plugins: - - staticfloat/cryptic: - variables: - - CODECOV_TOKEN="U2FsdGVkX19l0fhdBabbuiEdysyEabkJLRHfxm7CNRkuGbnwPV365sxxC7Czs/CVcws0N1oB4pVwALRRMe36oA==" - - COVERALLS_TOKEN="U2FsdGVkX19zopI0hMNzzi2UUOvNVFD8Y0iisFnO/ryVxU7Tit8ZEaeN+gxodRx4CosUUh192F1+q3dTMWRIvw==" - - JuliaCI/julia#v1: - version: 1.6 - - staticfloat/sandbox#v1: - rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v1/llvm-passes.tar.gz - rootfs_treehash: "f3ed53f159e8f13edfba8b20ebdb8ece73c1b8a8" - uid: 1000 - gid: 1000 - commands: | - echo "--- Build Julia from source" - make -j 6 - - echo "--- Print Julia version info" - ./julia -e 'using InteractiveUtils; InteractiveUtils.versioninfo()' - ./julia -e '@info "" Sys.CPU_THREADS' - # this is necessary to make sure that the LibGit2 tests passes - git config --global init.defaultBranch master - - echo "--- Run some Julia tests in serial" - ./julia --code-coverage=all --sysimage-native-code=no .buildkite/coverage-linux64/run_tests_serial.jl test/compiler/codegen.jl - ./julia --code-coverage=all --sysimage-native-code=no .buildkite/coverage-linux64/run_tests_serial.jl test/compiler/contextual.jl - ./julia --code-coverage=all --sysimage-native-code=no .buildkite/coverage-linux64/run_tests_serial.jl test/compiler/inference.jl - ./julia --code-coverage=all --sysimage-native-code=no .buildkite/coverage-linux64/run_tests_serial.jl test/compiler/inline.jl - ./julia --code-coverage=all --sysimage-native-code=no .buildkite/coverage-linux64/run_tests_serial.jl test/compiler/interpreter_exec.jl - ./julia --code-coverage=all --sysimage-native-code=no .buildkite/coverage-linux64/run_tests_serial.jl test/compiler/irpasses.jl - ./julia --code-coverage=all --sysimage-native-code=no .buildkite/coverage-linux64/run_tests_serial.jl test/compiler/ssair.jl - ./julia --code-coverage=all --sysimage-native-code=no .buildkite/coverage-linux64/run_tests_serial.jl test/compiler/validation.jl - - echo "--- Run Julia tests in parallel with code coverage enabled" - ./julia --code-coverage=all --sysimage-native-code=no .buildkite/coverage-linux64/run_tests_parallel.jl - - echo "--- Process and upload coverage information" - ./julia .buildkite/coverage-linux64/upload_coverage.jl - timeout_in_minutes: 600 # 600 minutes = 10 hours - -# We must accept the signed job id secret in order to propagate secrets -env: - BUILDKITE_PLUGIN_CRYPTIC_BASE64_SIGNED_JOB_ID_SECRET: ${BUILDKITE_PLUGIN_CRYPTIC_BASE64_SIGNED_JOB_ID_SECRET?} diff --git a/.buildkite/coverage-linux64/run_tests_parallel.jl b/.buildkite/coverage-linux64/run_tests_parallel.jl deleted file mode 100644 index 5386828aa4e14..0000000000000 --- a/.buildkite/coverage-linux64/run_tests_parallel.jl +++ /dev/null @@ -1,36 +0,0 @@ -# When running this file, make sure to set the `--code-coverage=all` command-line flag. - -# Important note: even if one or more tests fail, we will still exit with status code 0. - -# The reason for this is that we always want to upload code coverage, even if some of the -# tests fail. Therefore, even if the `coverage-linux64` pipeline passes, you should not -# assume that all of the tests passed. If you want to know if all of the tests are passing, -# please look at the status of the `tester_linux64` pipeline. - -const include_tests = String[] - -const exclude_tests = String[] - -empty!(Base.DEPOT_PATH) -push!(Base.DEPOT_PATH, mktempdir(; cleanup = true)) - -module ChooseTests - include(joinpath(dirname(dirname(@__DIR__)), "test", "choosetests.jl")) -end - -const tests = ChooseTests.choosetests() |> - first |> - x -> setdiff(x, exclude_tests) |> - x -> vcat(x, include_tests) |> - unique |> - sort - -const ncores = min(Sys.CPU_THREADS, Threads.nthreads()) - -@info "" ncores Sys.CPU_THREADS Threads.nthreads() - -try - Base.runtests(tests; ncores) -catch ex - @error "" exception=(ex, catch_backtrace()) -end diff --git a/.buildkite/coverage-linux64/run_tests_serial.jl b/.buildkite/coverage-linux64/run_tests_serial.jl deleted file mode 100644 index 6d7380a55e402..0000000000000 --- a/.buildkite/coverage-linux64/run_tests_serial.jl +++ /dev/null @@ -1,16 +0,0 @@ -using Test - -const repository_root = dirname(dirname(@__DIR__)) - -for filename in ARGS - path = joinpath(repository_root, filename) - @info "Starting $(filename)" - try - @testset "$(filename)" begin - include(path) - end - catch ex - @error "" exception=(ex, catch_backtrace()) - end - @info "Finished $(filename)" -end diff --git a/.buildkite/experimental/pipeline.yml b/.buildkite/experimental/pipeline.yml deleted file mode 100644 index 6f86f7ef243e5..0000000000000 --- a/.buildkite/experimental/pipeline.yml +++ /dev/null @@ -1,19 +0,0 @@ -# This file launches all the build jobs that _don't_ require secrets access. -# These jobs can pass their output off to jobs that do require secrets access, -# but those privileged steps require signing before they can be run. -# -# Yes, this is creating another layer of indirection; the flow now looks like: -# -# [webui] -> pipeline.yml -> llvm_passes.yml -# -# when we could theoretically just have the `webui` launch `llvm_passes.yml`, -# however this raises the bar for contributors to add new (unsigned) steps to -# our CI configuration, so I'd rather live with an extra layer of indirection -# and only need to touch the webui configuration when we need to alter -# something about the privileged steps. -steps: - - label: ":buildkite: Launch unsigned pipelines" - commands: | - buildkite-agent pipeline upload .buildkite/experimental/sanitizers.yml - agents: - queue: julia diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml deleted file mode 100644 index 3a3ebc718cbaa..0000000000000 --- a/.buildkite/pipeline.yml +++ /dev/null @@ -1,28 +0,0 @@ -# This file launches all the build jobs that _don't_ require secrets access. -# These jobs can pass their output off to jobs that do require secrets access, -# but those privileged steps require signing before they can be run. -# -# Yes, this is creating another layer of indirection; the flow now looks like: -# -# [webui] -> pipeline.yml -> misc/whitespace.yml -# -# when we could theoretically just have the `webui` launch `misc/whitespace.yml`, -# however this raises the bar for contributors to add new (unsigned) steps to -# our CI configuration, so I'd rather live with an extra layer of indirection -# and only need to touch the webui configuration when we need to alter -# something about the privileged steps. -steps: - - label: ":buildkite: Launch unsigned pipelines" - commands: | - # First, we launch whitespace, because we want that pipeline to finish as quickly as possible. - buildkite-agent pipeline upload .buildkite/misc/whitespace.yml - - # Next, we launch the miscellaneous pipelines in alphabetical order. - buildkite-agent pipeline upload .buildkite/misc/doctest.yml - buildkite-agent pipeline upload .buildkite/misc/embedding.yml - buildkite-agent pipeline upload .buildkite/misc/llvmpasses.yml - - # Finally, we launch the platform pipelines in alphabetical order. - buildkite-agent pipeline upload .buildkite/platforms/linux64.yml - agents: - queue: julia diff --git a/.buildkite/experimental/0_webui.yml b/.buildkite/pipelines/experimental/0_webui.yml similarity index 67% rename from .buildkite/experimental/0_webui.yml rename to .buildkite/pipelines/experimental/0_webui.yml index ab3f68db4c393..54dbbc59d4256 100644 --- a/.buildkite/experimental/0_webui.yml +++ b/.buildkite/pipelines/experimental/0_webui.yml @@ -15,4 +15,10 @@ steps: # but some of our signed pipelines can wait upon the completion of these unsigned # pipelines. unsigned_pipelines: - - .buildkite/experimental/pipeline.yml + - .buildkite/pipelines/experimental/launch_unsigned_builders.yml + + # Our signed pipelines must have a `signature` or `signature_file` parameter that + # verifies the treehash of the pipeline itself and the inputs listed in `inputs` + # signed_pipelines: + # - pipeline: .buildkite/pipelines/experimental/misc/foo_bar_baz.yml + # signature: "my_signature" diff --git a/.buildkite/pipelines/experimental/README.md b/.buildkite/pipelines/experimental/README.md new file mode 100644 index 0000000000000..f92aac7a1af02 --- /dev/null +++ b/.buildkite/pipelines/experimental/README.md @@ -0,0 +1,7 @@ +## Experimental pipeline (`master` branch only) + +This is the [`julia-master->experimental`](https://buildkite.com/julialang/julia-master-experimental) pipeline. + +We use this pipeline for builders that are not yet stable enough to go into the main pipeline. + +These builders are triggered by GitHub webhook events, such as pushes and pull requests. diff --git a/.buildkite/pipelines/experimental/launch_unsigned_builders.yml b/.buildkite/pipelines/experimental/launch_unsigned_builders.yml new file mode 100644 index 0000000000000..f023e19a5c940 --- /dev/null +++ b/.buildkite/pipelines/experimental/launch_unsigned_builders.yml @@ -0,0 +1,6 @@ +steps: + - label: ":buildkite: Launch unsigned pipelines" + commands: | + buildkite-agent pipeline upload .buildkite/pipelines/experimental/misc/sanitizers.yml + agents: + queue: julia diff --git a/.buildkite/experimental/sanitizers.yml b/.buildkite/pipelines/experimental/misc/sanitizers.yml similarity index 67% rename from .buildkite/experimental/sanitizers.yml rename to .buildkite/pipelines/experimental/misc/sanitizers.yml index 534dac81e53f3..67c0b547d4b20 100644 --- a/.buildkite/experimental/sanitizers.yml +++ b/.buildkite/pipelines/experimental/misc/sanitizers.yml @@ -1,6 +1,3 @@ -# These steps should only run on `sandbox.jl` machines, not `docker`-isolated ones -# since we need nestable sandboxing. The rootfs images being used here are built from -# the `.buildkite/rootfs_images/llvm-passes.jl` file. agents: queue: "julia" # Only run on `sandbox.jl` machines (not `docker`-isolated ones) since we need nestable sandboxing @@ -14,8 +11,8 @@ steps: - JuliaCI/julia#v1: version: 1.6 - staticfloat/sandbox#v1: - rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v2.0/llvm_passes.tar.gz - rootfs_treehash: "0b5a80c1d0ab110a57fbdb7f4bc042a5ede310f3" + rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v3.1/llvm_passes.x86_64.tar.gz + rootfs_treehash: "9dd715500b117a16fcfa419ea0bca0c0ca902cee" uid: 1000 gid: 1000 workspaces: @@ -29,6 +26,6 @@ steps: echo "--- Test that ASAN is enabled" contrib/asan/check.jl ./tmp/test-asan/asan/usr/bin/julia-debug timeout_in_minutes: 120 - # notify: - # - github_commit_status: - # context: "asan" + # notify: # TODO: uncomment this line + # - github_commit_status: # TODO: uncomment this line + # context: "asan" # TODO: uncomment this line diff --git a/.buildkite/0_webui.yml b/.buildkite/pipelines/main/0_webui.yml similarity index 89% rename from .buildkite/0_webui.yml rename to .buildkite/pipelines/main/0_webui.yml index 440d2d443ce7e..96dc81cef36fe 100644 --- a/.buildkite/0_webui.yml +++ b/.buildkite/pipelines/main/0_webui.yml @@ -15,10 +15,10 @@ steps: # but some of our signed pipelines can wait upon the completion of these unsigned # pipelines. unsigned_pipelines: - - .buildkite/pipeline.yml + - .buildkite/pipelines/main/launch_unsigned_builders.yml # Our signed pipelines must have a `signature` or `signature_file` parameter that # verifies the treehash of the pipeline itself and the inputs listed in `inputs` signed_pipelines: - - pipeline: .buildkite/signed_pipeline_test.yml + - pipeline: .buildkite/pipelines/main/misc/signed_pipeline_test.yml signature: "U2FsdGVkX18ZrMlORSIi0TvW99eZ3JyUEhntMyXjrOSJ9jAtUohgHc8+dMnWUc6qWjYt8k63wfPrth33SGWDiF814Bm1W5Zk3+R6HgVu6UCrQEI5sLm+SJPbrvET+Jkn" diff --git a/.buildkite/pipelines/main/README.md b/.buildkite/pipelines/main/README.md new file mode 100644 index 0000000000000..6b9d67bd7cc3a --- /dev/null +++ b/.buildkite/pipelines/main/README.md @@ -0,0 +1,15 @@ +## Main pipeline + +This is the main pipeline. It contains most of the builders. These builders are triggered by GitHub webhook events, such as pushes and pull requests. + +We have a different main pipeline for each permanent branch. + +For example: + +| Permanent Branch | Pipeline | +| ---------------- | -------------------------------------------------------------------------------- | +| `master` | [`julia-master`](https://buildkite.com/julialang/julia-master) | +| `release-1.6` | [`julia-release-1.6`](https://buildkite.com/julialang/julia-release-1-dot-6) | +| `release-1.7` | [`julia-release-1.7`](https://buildkite.com/julialang/julia-release-1-dot-7) | + +(This is not a complete list.) diff --git a/.buildkite/pipelines/main/launch_unsigned_builders.yml b/.buildkite/pipelines/main/launch_unsigned_builders.yml new file mode 100644 index 0000000000000..6e9f0f0d8fa23 --- /dev/null +++ b/.buildkite/pipelines/main/launch_unsigned_builders.yml @@ -0,0 +1,29 @@ +# This file launches all the build jobs that _don't_ require secrets access. +# These jobs can pass their output off to jobs that do require secrets access, +# but those privileged steps require signing before they can be run. +# +# Yes, this is creating another layer of indirection; the flow now looks like: +# +# [webui] -> launch_unsigned_builders.yml -> misc/whitespace.yml +# +# when we could theoretically just have the `webui` launch `misc/whitespace.yml`, +# however this raises the bar for contributors to add new (unsigned) steps to +# our CI configuration, so I'd rather live with an extra layer of indirection +# and only need to touch the webui configuration when we need to alter +# something about the privileged steps. + +steps: + - label: ":buildkite: Launch unsigned builders" + commands: | + # First, we launch the `whitespace` builder, because we want that builder to finish as quickly as possible. + buildkite-agent pipeline upload .buildkite/pipelines/main/misc/whitespace.yml + + # Next, we launch the miscellaneous builders in alphabetical order. + buildkite-agent pipeline upload .buildkite/pipelines/main/misc/doctest.yml + buildkite-agent pipeline upload .buildkite/pipelines/main/misc/embedding.yml + buildkite-agent pipeline upload .buildkite/pipelines/main/misc/llvmpasses.yml + + # Finally, we launch the platform builders (`package_*`) and (`tester_*`) in alphabetical order. + buildkite-agent pipeline upload .buildkite/pipelines/main/platforms/linux64.yml + agents: + queue: julia diff --git a/.buildkite/misc/doctest.yml b/.buildkite/pipelines/main/misc/doctest.yml similarity index 71% rename from .buildkite/misc/doctest.yml rename to .buildkite/pipelines/main/misc/doctest.yml index 234e49f5dcf53..0a5dc29bcb1c7 100644 --- a/.buildkite/misc/doctest.yml +++ b/.buildkite/pipelines/main/misc/doctest.yml @@ -1,6 +1,3 @@ -# These steps should only run on `sandbox.jl` machines, not `docker`-isolated ones -# since we need nestable sandboxing. The rootfs images being used here are built from -# the `.buildkite/rootfs_images/llvm-passes.jl` file. agents: queue: "julia" # Only run on `sandbox.jl` machines (not `docker`-isolated ones) since we need nestable sandboxing @@ -14,8 +11,8 @@ steps: - JuliaCI/julia#v1: version: 1.6 - staticfloat/sandbox#v1: - rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v3.0/package_linux.x86_64.tar.gz - rootfs_treehash: "d5722d586b93eb307bb6340d275afdbf7578a756" + rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v3.1/package_linux.x86_64.tar.gz + rootfs_treehash: "8c33c341a864852629b8aac01a6eb6a79b73570e" uid: 1000 gid: 1000 workspaces: @@ -33,7 +30,7 @@ steps: echo "--- Run Julia doctests" JULIA_NUM_THREADS=1 make -C doc doctest=true - timeout_in_minutes: 120 + timeout_in_minutes: 45 notify: - github_commit_status: context: "doctest" diff --git a/.buildkite/misc/embedding.yml b/.buildkite/pipelines/main/misc/embedding.yml similarity index 76% rename from .buildkite/misc/embedding.yml rename to .buildkite/pipelines/main/misc/embedding.yml index 31f85633479a4..087ca0f68eb3d 100644 --- a/.buildkite/misc/embedding.yml +++ b/.buildkite/pipelines/main/misc/embedding.yml @@ -1,6 +1,3 @@ -# These steps should only run on `sandbox.jl` machines, not `docker`-isolated ones -# since we need nestable sandboxing. The rootfs images being used here are built from -# the `.buildkite/rootfs_images/llvm-passes.jl` file. agents: queue: "julia" # Only run on `sandbox.jl` machines (not `docker`-isolated ones) since we need nestable sandboxing @@ -14,8 +11,8 @@ steps: - JuliaCI/julia#v1: version: 1.6 - staticfloat/sandbox#v1: - rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v3.0/package_linux.x86_64.tar.gz - rootfs_treehash: "d5722d586b93eb307bb6340d275afdbf7578a756" + rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v3.1/package_linux.x86_64.tar.gz + rootfs_treehash: "8c33c341a864852629b8aac01a6eb6a79b73570e" uid: 1000 gid: 1000 workspaces: diff --git a/.buildkite/misc/llvmpasses.yml b/.buildkite/pipelines/main/misc/llvmpasses.yml similarity index 83% rename from .buildkite/misc/llvmpasses.yml rename to .buildkite/pipelines/main/misc/llvmpasses.yml index 7660b3978e967..eed2f957855bb 100644 --- a/.buildkite/misc/llvmpasses.yml +++ b/.buildkite/pipelines/main/misc/llvmpasses.yml @@ -1,6 +1,3 @@ -# These steps should only run on `sandbox.jl` machines, not `docker`-isolated ones -# since we need nestable sandboxing. The rootfs images being used here are built from -# the `.buildkite/rootfs_images/llvm-passes.jl` file. agents: queue: "julia" # Only run on `sandbox.jl` machines (not `docker`-isolated ones) since we need nestable sandboxing @@ -36,8 +33,8 @@ steps: - JuliaCI/julia#v1: version: 1.6 - staticfloat/sandbox#v1: - rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v3.0/package_linux.x86_64.tar.gz - rootfs_treehash: "d5722d586b93eb307bb6340d275afdbf7578a756" + rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v3.1/package_linux.x86_64.tar.gz + rootfs_treehash: "8c33c341a864852629b8aac01a6eb6a79b73570e" uid: 1000 gid: 1000 workspaces: diff --git a/.buildkite/signed_pipeline_test.yml b/.buildkite/pipelines/main/misc/signed_pipeline_test.yml similarity index 100% rename from .buildkite/signed_pipeline_test.yml rename to .buildkite/pipelines/main/misc/signed_pipeline_test.yml diff --git a/.buildkite/misc/whitespace.yml b/.buildkite/pipelines/main/misc/whitespace.yml similarity index 63% rename from .buildkite/misc/whitespace.yml rename to .buildkite/pipelines/main/misc/whitespace.yml index 01b4c79e7822b..3f9bf13421d8e 100644 --- a/.buildkite/misc/whitespace.yml +++ b/.buildkite/pipelines/main/misc/whitespace.yml @@ -1,6 +1,3 @@ -# These steps should only run on `sandbox.jl` machines, not `docker`-isolated ones -# since we need nestable sandboxing. The rootfs images being used here are built from -# the `.buildkite/rootfs_images/llvm-passes.jl` file. agents: queue: "julia" # Only run on `sandbox.jl` machines (not `docker`-isolated ones) since we need nestable sandboxing @@ -14,8 +11,8 @@ steps: - JuliaCI/julia#v1: version: 1.6 - staticfloat/sandbox#v1: - rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v3.0/package_linux.x86_64.tar.gz - rootfs_treehash: "d5722d586b93eb307bb6340d275afdbf7578a756" + rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v3.1/package_linux.x86_64.tar.gz + rootfs_treehash: "8c33c341a864852629b8aac01a6eb6a79b73570e" workspaces: - "/cache/repos:/cache/repos" commands: | diff --git a/.buildkite/platforms/linux64.yml b/.buildkite/pipelines/main/platforms/linux64.yml similarity index 79% rename from .buildkite/platforms/linux64.yml rename to .buildkite/pipelines/main/platforms/linux64.yml index 69befe1064df7..7780c574951e8 100644 --- a/.buildkite/platforms/linux64.yml +++ b/.buildkite/pipelines/main/platforms/linux64.yml @@ -1,6 +1,3 @@ -# These steps should only run on `sandbox.jl` machines, not `docker`-isolated ones -# since we need nestable sandboxing. The rootfs images being used here are built from -# the `.buildkite/rootfs_images/llvm-passes.jl` file. agents: queue: "julia" # Only run on `sandbox.jl` machines (not `docker`-isolated ones) since we need nestable sandboxing @@ -14,8 +11,8 @@ steps: - JuliaCI/julia#v1: version: 1.6 - staticfloat/sandbox#v1: - rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v3.0/package_linux.x86_64.tar.gz - rootfs_treehash: "d5722d586b93eb307bb6340d275afdbf7578a756" + rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v3.1/package_linux.x86_64.tar.gz + rootfs_treehash: "8c33c341a864852629b8aac01a6eb6a79b73570e" uid: 1000 gid: 1000 workspaces: @@ -42,6 +39,7 @@ steps: - github_commit_status: context: "package_linux64" + # TODO: uncomment the following lines in order to enable the `tester_linux64` builder # - label: "tester_linux64" # key: tester_linux64 # depends_on: package_linux64 @@ -50,8 +48,8 @@ steps: # version: 1.6 # - staticfloat/sandbox#v1: # # TODO: use a separate `tester_linux` image, instead of using the `package_linux` image. - # rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v3.0/package_linux.x86_64.tar.gz - # rootfs_treehash: "d5722d586b93eb307bb6340d275afdbf7578a756" + # rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v3.1/package_linux.x86_64.tar.gz + # rootfs_treehash: "8c33c341a864852629b8aac01a6eb6a79b73570e" # uid: 1000 # gid: 1000 # workspaces: @@ -73,7 +71,7 @@ steps: # # echo "--- Run the Julia test suite" # unset JULIA_DEPOT_PATH - # julia-artifact/bin/julia .buildkite/rr_capture.jl julia-artifact/bin/julia -e 'Base.runtests(["all"]; ncores = Sys.CPU_THREADS)' + # julia-artifact/bin/julia .buildkite/utilities/rr/rr_capture.jl julia-artifact/bin/julia -e 'Base.runtests(["all"]; ncores = Sys.CPU_THREADS)' # timeout_in_minutes: 120 # notify: # - github_commit_status: diff --git a/.buildkite/pipelines/scheduled/0_webui.yml b/.buildkite/pipelines/scheduled/0_webui.yml new file mode 100644 index 0000000000000..8aaf812376b5c --- /dev/null +++ b/.buildkite/pipelines/scheduled/0_webui.yml @@ -0,0 +1,24 @@ +# This file represents what is put into the webUI. +# It is purely for keeping track of the changes we make to the webUI configuration; modifying this file has no effect. +# We use the `cryptic` buildkite plugin to provide secrets management, which requires some integration into the WebUI's steps. +agents: + queue: "julia" + sandbox.jl: "true" + +steps: + - label: ":unlock: Unlock secrets, launch pipelines" + plugins: + - staticfloat/cryptic: + # Our list of pipelines that should be launched (but don't require a signature) + # These pipelines can be modified by any contributor and CI will still run. + # Build secrets will not be available in these pipelines (or their children) + # but some of our signed pipelines can wait upon the completion of these unsigned + # pipelines. + # unsigned_pipelines: + # - .buildkite/pipelines/scheduled/launch_unsigned_builders.yml + + # Our signed pipelines must have a `signature` or `signature_file` parameter that + # verifies the treehash of the pipeline itself and the inputs listed in `inputs` + signed_pipelines: + - pipeline: .buildkite/pipelines/scheduled/coverage/coverage_linux64.yml + signature: "U2FsdGVkX1+lpFo/nKzx3c6xCZPKYTAuunXpOsZG4+s4+iU5LfEpMvtNvpKQjDugRoxQxCItMqB6vr4KZN3KtKhjkLbr8ExAyaPil/N/uFhrLlpwNem9dxHbPrU2l7qo" diff --git a/.buildkite/pipelines/scheduled/README.md b/.buildkite/pipelines/scheduled/README.md new file mode 100644 index 0000000000000..ca071dceb2a44 --- /dev/null +++ b/.buildkite/pipelines/scheduled/README.md @@ -0,0 +1,5 @@ +## Scheduled pipeline (`master` branch only) + +This is the [`julia-master->scheduled`](https://buildkite.com/julialang/julia-master-scheduled) pipeline. + +We use this pipeline for scheduled builds. The builders in this pipeline run on a schedule once per day. They are not triggered by GitHub webhooks. diff --git a/.buildkite/pipelines/scheduled/coverage/coverage_linux64.yml b/.buildkite/pipelines/scheduled/coverage/coverage_linux64.yml new file mode 100644 index 0000000000000..ce7a3aca4227d --- /dev/null +++ b/.buildkite/pipelines/scheduled/coverage/coverage_linux64.yml @@ -0,0 +1,40 @@ +agents: + queue: "julia" + # Only run on `sandbox.jl` machines (not `docker`-isolated ones) since we need nestable sandboxing + sandbox.jl: "true" + os: "linux" + +steps: + - label: ":unlock: :coverage: Run coverage test" + plugins: + - staticfloat/cryptic: + variables: + - CODECOV_TOKEN="U2FsdGVkX19l0fhdBabbuiEdysyEabkJLRHfxm7CNRkuGbnwPV365sxxC7Czs/CVcws0N1oB4pVwALRRMe36oA==" + - COVERALLS_TOKEN="U2FsdGVkX19zopI0hMNzzi2UUOvNVFD8Y0iisFnO/ryVxU7Tit8ZEaeN+gxodRx4CosUUh192F1+q3dTMWRIvw==" + - JuliaCI/julia#v1: + version: 1.6 + - staticfloat/sandbox#v1: + rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v3.1/package_linux.x86_64.tar.gz + rootfs_treehash: "8c33c341a864852629b8aac01a6eb6a79b73570e" + uid: 1000 + gid: 1000 + commands: | + echo "--- Build Julia from source" + make -j 6 + + echo "--- Print Julia version info" + ./julia -e 'using InteractiveUtils; InteractiveUtils.versioninfo()' + ./julia -e '@info "" Sys.CPU_THREADS' + # this is necessary to make sure that the LibGit2 tests passes + git config --global init.defaultBranch master + + echo "--- Run Julia tests in parallel with code coverage enabled" + ./julia --code-coverage=all --sysimage-native-code=no .buildkite/pipelines/scheduled/coverage/run_tests_parallel.jl + + echo "--- Process and upload coverage information" + ./julia .buildkite/pipelines/scheduled/coverage/upload_coverage.jl + timeout_in_minutes: 240 # 240 minutes = 4 hours + +# We must accept the signed job id secret in order to propagate secrets +env: + BUILDKITE_PLUGIN_CRYPTIC_BASE64_SIGNED_JOB_ID_SECRET: ${BUILDKITE_PLUGIN_CRYPTIC_BASE64_SIGNED_JOB_ID_SECRET?} diff --git a/.buildkite/pipelines/scheduled/coverage/run_tests_parallel.jl b/.buildkite/pipelines/scheduled/coverage/run_tests_parallel.jl new file mode 100644 index 0000000000000..6da608b5e8be9 --- /dev/null +++ b/.buildkite/pipelines/scheduled/coverage/run_tests_parallel.jl @@ -0,0 +1,25 @@ +# Important note: even if one or more tests fail, we will still exit with status code 0. + +# The reason for this is that we always want to upload code coverage, even if some of the +# tests fail. Therefore, even if the `coverage_linux64` builder passes, you should not +# assume that all of the tests passed. If you want to know if all of the tests are passing, +# please look at the status of the `tester_*` builders (e.g. `tester_linux64`). + +# When running this file, make sure to set all of the following command-line flags: +# 1. `--code-coverage=all` +# 2. `--sysimage-native-code=no` + +empty!(Base.DEPOT_PATH) +push!(Base.DEPOT_PATH, mktempdir(; cleanup = true)) + +const tests = "all" +const ncores = Sys.CPU_THREADS + +@info "" Sys.CPU_THREADS +@info "" tests ncores + +try + Base.runtests(tests; ncores) +catch ex + @error "" exception=(ex, catch_backtrace()) +end diff --git a/.buildkite/coverage-linux64/upload_coverage.jl b/.buildkite/pipelines/scheduled/coverage/upload_coverage.jl similarity index 100% rename from .buildkite/coverage-linux64/upload_coverage.jl rename to .buildkite/pipelines/scheduled/coverage/upload_coverage.jl diff --git a/.buildkite/pipelines/scheduled/launch_unsigned_builders.yml b/.buildkite/pipelines/scheduled/launch_unsigned_builders.yml new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/.buildkite/rr_capture.jl b/.buildkite/utilities/rr/rr_capture.jl similarity index 100% rename from .buildkite/rr_capture.jl rename to .buildkite/utilities/rr/rr_capture.jl From ac3d472c2994c903cf0d480677400a47538af609 Mon Sep 17 00:00:00 2001 From: Dilum Aluthge Date: Sun, 25 Jul 2021 21:42:39 -0400 Subject: [PATCH 57/74] CI (Buildkite): include the short commit hash in the artifact filename (#41700) (cherry picked from commit 343c2b19bc83dfa58cbb701babba4a0721e18903) --- .../pipelines/main/platforms/linux64.yml | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/.buildkite/pipelines/main/platforms/linux64.yml b/.buildkite/pipelines/main/platforms/linux64.yml index 7780c574951e8..1e88db1144b4c 100644 --- a/.buildkite/pipelines/main/platforms/linux64.yml +++ b/.buildkite/pipelines/main/platforms/linux64.yml @@ -19,6 +19,17 @@ steps: # Include `/cache/repos` so that our `git` version introspection works. - "/cache/repos:/cache/repos" commands: | + echo "--- Print the short and long commit hashes" + SHORT_COMMIT_LENGTH=10 + SHORT_COMMIT=`echo $$BUILDKITE_COMMIT | cut -c1-$$SHORT_COMMIT_LENGTH` + JULIA_DIRECTORY_NAME="julia-$$SHORT_COMMIT" + JULIA_BINARYDIST_FILENAME=`make print-JULIA_BINARYDIST_FILENAME | cut -c27-` + ARTIFACT_FILE_EXTENSION="tar.gz" + ARTIFACT_FILENAME="$$JULIA_BINARYDIST_FILENAME.$$ARTIFACT_FILE_EXTENSION" + echo "The full commit is $$BUILDKITE_COMMIT" + echo "The Julia directory name will be $$JULIA_DIRECTORY_NAME" + echo "The artifact filename will be $$ARTIFACT_FILENAME" + echo "--- Build Julia from source" make -j 6 make release @@ -28,12 +39,13 @@ steps: ./julia -e 'using InteractiveUtils; InteractiveUtils.versioninfo()' echo "--- Compress build artifacts" - mv julia-* julia-artifact - rm -rf julia-linux64.tar.gz - tar czf julia-linux64.tar.gz julia-artifact/ + ls -ld $$JULIA_DIRECTORY_NAME/ + rm -rf $$ARTIFACT_FILENAME + tar czf $$ARTIFACT_FILENAME $$JULIA_DIRECTORY_NAME/ + ls -l $$ARTIFACT_FILENAME echo "--- Upload build artifacts" - buildkite-agent artifact upload julia-linux64.tar.gz + buildkite-agent artifact upload $$ARTIFACT_FILENAME timeout_in_minutes: 60 notify: - github_commit_status: From 2b7080844ec98e2d0adf2f7654348fdf66d8485f Mon Sep 17 00:00:00 2001 From: Dilum Aluthge Date: Sun, 25 Jul 2021 22:20:55 -0400 Subject: [PATCH 58/74] CI (Buildkite): for the signed pipeline test, use `signature_file` instead of `signature` (#41706) * CI (Buildkite): for the signed pipeline test, use `signature_file` instead of `signature` * Base64-decode the signature before writing it to the signature file (cherry picked from commit f7f46af8ff39a1b4c7000651c680058e9c0639f5) --- .buildkite/pipelines/main/0_webui.yml | 2 +- .../pipelines/main/misc/signed_pipeline_test.yml.signature | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 .buildkite/pipelines/main/misc/signed_pipeline_test.yml.signature diff --git a/.buildkite/pipelines/main/0_webui.yml b/.buildkite/pipelines/main/0_webui.yml index 96dc81cef36fe..8e7b9c58ea423 100644 --- a/.buildkite/pipelines/main/0_webui.yml +++ b/.buildkite/pipelines/main/0_webui.yml @@ -21,4 +21,4 @@ steps: # verifies the treehash of the pipeline itself and the inputs listed in `inputs` signed_pipelines: - pipeline: .buildkite/pipelines/main/misc/signed_pipeline_test.yml - signature: "U2FsdGVkX18ZrMlORSIi0TvW99eZ3JyUEhntMyXjrOSJ9jAtUohgHc8+dMnWUc6qWjYt8k63wfPrth33SGWDiF814Bm1W5Zk3+R6HgVu6UCrQEI5sLm+SJPbrvET+Jkn" + signature_file: .buildkite/pipelines/main/misc/signed_pipeline_test.yml.signature diff --git a/.buildkite/pipelines/main/misc/signed_pipeline_test.yml.signature b/.buildkite/pipelines/main/misc/signed_pipeline_test.yml.signature new file mode 100644 index 0000000000000..10220c758086a --- /dev/null +++ b/.buildkite/pipelines/main/misc/signed_pipeline_test.yml.signature @@ -0,0 +1 @@ +Salted__¬ÉNE""Ñ;Ö÷יܜ”í3%ã¬ä‰ö0-Rˆ`Ï>tÉÖQΪZ6-òN·Áóë¶÷Heƒˆ_5àµ[–dßäzné@«@B9°¹¾H“Û®ñø™' \ No newline at end of file From 80b456d7e9814701e2bd65ca51229509f6df6e03 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Sun, 18 Jul 2021 13:13:06 +0200 Subject: [PATCH 59/74] [LLVM] upgrade LLVM to 12.0.1 (cherry picked from commit 5386fa6cfbc7ac0c0c1c2464c7d7dd79cf829a35) --- deps/Versions.make | 10 +- deps/checksums/clang | 116 ++++---- deps/checksums/llvm | 476 ++++++++++++++++---------------- doc/src/devdocs/llvm.md | 2 +- stdlib/libLLVM_jll/Project.toml | 2 +- 5 files changed, 299 insertions(+), 307 deletions(-) diff --git a/deps/Versions.make b/deps/Versions.make index 770828e28d93c..2d29b0bf0b470 100644 --- a/deps/Versions.make +++ b/deps/Versions.make @@ -15,7 +15,7 @@ CSL_JLL_NAME := CompilerSupportLibraries # Clang (paired with LLVM, only here as a JLL download) CLANG_JLL_NAME := Clang -CLANG_JLL_VER := 12.0.0+1 +CLANG_JLL_VER := 12.0.1+0 # DSFMT DSFMT_VER := 2.2.4 @@ -44,14 +44,14 @@ LIBUV_VER := 2 LIBUV_JLL_NAME := LibUV # LLVM -LLVM_VER := 12.0.0 -LLVM_ASSERT_JLL_VER := 12.0.0+1 +LLVM_VER := 12.0.1 +LLVM_ASSERT_JLL_VER := 12.0.1+0 LLVM_JLL_NAME := libLLVM # LLVM_tools (downloads LLVM_jll to get things like `lit` and `opt`) LLVM_TOOLS_JLL_NAME := LLVM -LLVM_TOOLS_JLL_VER := 12.0.0+1 -LLVM_TOOLS_ASSERT_JLL_VER := 12.0.0+1 +LLVM_TOOLS_JLL_VER := 12.0.1+0 +LLVM_TOOLS_ASSERT_JLL_VER := 12.0.1+0 # LLVM libunwind LLVMUNWIND_VER := 11.0.1 diff --git a/deps/checksums/clang b/deps/checksums/clang index 125b200da0a36..6d6d4d100a432 100644 --- a/deps/checksums/clang +++ b/deps/checksums/clang @@ -1,58 +1,58 @@ -Clang.v12.0.0+1.aarch64-apple-darwin.tar.gz/md5/465b3375db7ab6b93fbe465ed76a275d -Clang.v12.0.0+1.aarch64-apple-darwin.tar.gz/sha512/a39faf3bb411612da5cb29be70a3b200dac3a4bfd7eb58e4f68edfd09923819f7f465dab4dde4caa0335d8fc392b2f55db762de0e93642ff49a466b68f0fd383 -Clang.v12.0.0+1.aarch64-linux-gnu-cxx03.tar.gz/md5/162a2ee947742b9d0c01c95725b98d96 -Clang.v12.0.0+1.aarch64-linux-gnu-cxx03.tar.gz/sha512/ead804d78ab42d3e1ca6cb7f12ff7544525772badce779eaef5cf973e23966f1398343d3c3148b58195eef7d4e9c7ee897e8bfb30a24c095685cece46344671e -Clang.v12.0.0+1.aarch64-linux-gnu-cxx11.tar.gz/md5/563e93b82893c8257c23878135de6687 -Clang.v12.0.0+1.aarch64-linux-gnu-cxx11.tar.gz/sha512/ce8103e409790b5d4993ef4259524096617ee27b82b5d1f6c55880814211da6cefb4645a9c5de4ec44f9c961d1ec62da8cde0977d8af4be6e25a638891efc372 -Clang.v12.0.0+1.aarch64-linux-musl-cxx03.tar.gz/md5/d3eac2234c6fa736c3c8e8a4a7e9eb0c -Clang.v12.0.0+1.aarch64-linux-musl-cxx03.tar.gz/sha512/0a7f414dd22d34184c47695b5ad40e57286527a16fe32e90eaccad11d72192679985a9ffd6f9616564ff87de1d189726c3049100269648115f0f983d80400400 -Clang.v12.0.0+1.aarch64-linux-musl-cxx11.tar.gz/md5/23cdec7b732c13313c897593c40bce2a -Clang.v12.0.0+1.aarch64-linux-musl-cxx11.tar.gz/sha512/616fcd76d887cb3188b5dab8a2a15f276f3cc7d73ebdc13e1e12d1d4eaf0a3722ee288b5531bd24ab825a463112052399ab75d839e9df1c98987313fe731a2ef -Clang.v12.0.0+1.armv6l-linux-gnueabihf-cxx03.tar.gz/md5/f2d3d99ae67b8435021b20bd77aaf433 -Clang.v12.0.0+1.armv6l-linux-gnueabihf-cxx03.tar.gz/sha512/7cb4ac7392501a849058822f88aac49f9a0a03496a5fb39b8a8fcfeecf86f004b466e9fbfe2bfdaaed6d9cbe33e61b42d89c03ffddbfc4d8015790f64ca3623b -Clang.v12.0.0+1.armv6l-linux-gnueabihf-cxx11.tar.gz/md5/3c43e3cbbea5c8f2f197bf6c505a98c4 -Clang.v12.0.0+1.armv6l-linux-gnueabihf-cxx11.tar.gz/sha512/31107abd43a3ad43a3df424e9d35739d646c955923c08ca3cc405b7677deacc0cf9aaaf29b29fdd4fd53a434087620317e1f4d91c3bcb2932716a87804388d0b -Clang.v12.0.0+1.armv6l-linux-musleabihf-cxx03.tar.gz/md5/dd2eecb77a209c088ad81dec1f4d9610 -Clang.v12.0.0+1.armv6l-linux-musleabihf-cxx03.tar.gz/sha512/7a5a13ed5e046fb05cba3cd7aa55cdef741a7d76274e71d2b2fa194f132bb98c40d200fb04dc111cda7d901babd4f1f5d4e9bdf1dfd635f0492c386971878b5a -Clang.v12.0.0+1.armv6l-linux-musleabihf-cxx11.tar.gz/md5/74684a3dfdecad109aa1cb3e5eb1f24b -Clang.v12.0.0+1.armv6l-linux-musleabihf-cxx11.tar.gz/sha512/e1dae1ae3bd5b82d21401cbc9c6ca2281a05bb1039fffe0d94e7d5ef482a09bedbb5c512aae52873ec7ca471e543c334ff37b1e8429da79724b6b131b0502bf5 -Clang.v12.0.0+1.armv7l-linux-gnueabihf-cxx03.tar.gz/md5/32284100f6a57f5e4b32d0e6d35dff9c -Clang.v12.0.0+1.armv7l-linux-gnueabihf-cxx03.tar.gz/sha512/201cff5571219df602ea2f63d9559e8345aacc8c8691b30614fe6b6f5d0b7692f670b17366185f0e16cd1119bc49cdd1184247b32826bcc0a3a1d026c48e538b -Clang.v12.0.0+1.armv7l-linux-gnueabihf-cxx11.tar.gz/md5/c854231dcdd3816078ffaf435b152a3c -Clang.v12.0.0+1.armv7l-linux-gnueabihf-cxx11.tar.gz/sha512/082760f1dcb39cccffd5fa0a096ff0c6d823355d22d8cc2b69aa90092fb6157c87070d932fa736e3ddf4de0199c7f06cdca91bb354ee0cc125b505e66f5df068 -Clang.v12.0.0+1.armv7l-linux-musleabihf-cxx03.tar.gz/md5/5c909ab9d88334058e99be60e0330711 -Clang.v12.0.0+1.armv7l-linux-musleabihf-cxx03.tar.gz/sha512/abb39baac59aff579603870a31dbbbfebae3eea91caa203dbb3409d49cccd81dd96aa82a098c20265ee5f5fd851a0621c11b1a8837952a329c699b909e2c83a1 -Clang.v12.0.0+1.armv7l-linux-musleabihf-cxx11.tar.gz/md5/5c275a64299c0d4fc51d35f53c3dab00 -Clang.v12.0.0+1.armv7l-linux-musleabihf-cxx11.tar.gz/sha512/05c167d371dc5fa0226f0505ea1339ffcec8563c76adbc1450098ec7aa096fe04d855595d3cee290c2b6dc0843d8fc1c5215c84d3b3095d2cf0d93711dd4acec -Clang.v12.0.0+1.i686-linux-gnu-cxx03.tar.gz/md5/f27a08b7004c4a5eeb35d22198d72c82 -Clang.v12.0.0+1.i686-linux-gnu-cxx03.tar.gz/sha512/9fdcadb0d2bb56eb0e880a7b7a0c7660d614670209f76dfd5aae70ef0d3c437d6b56171b542d608784f7c4f7ef7bc5a4844baffae4fa95c25094c630ac39bfdb -Clang.v12.0.0+1.i686-linux-gnu-cxx11.tar.gz/md5/748c1efc36a70910fb3d3fea537c3b4e -Clang.v12.0.0+1.i686-linux-gnu-cxx11.tar.gz/sha512/bf70ba1a1576039210978488050890d6ee049fdab076a9a8498058b732c1c05d47861146aa48262a304f7dd8b24529e1a3425d0afc42c69843eac4b1317327a2 -Clang.v12.0.0+1.i686-linux-musl-cxx03.tar.gz/md5/5233ddc66968db6bd00bcc9e2aed7f12 -Clang.v12.0.0+1.i686-linux-musl-cxx03.tar.gz/sha512/bb9aea78c78c6cbb613b4c3eac6f08776dfafcc5402e6bf1a6670ac8d707de29b0ff8ad654d1d586f3e0b2a324c8fff49524033277f3cceb08c826243dd8a519 -Clang.v12.0.0+1.i686-linux-musl-cxx11.tar.gz/md5/f448936531ab804b56b0d8b63a2b7cb9 -Clang.v12.0.0+1.i686-linux-musl-cxx11.tar.gz/sha512/5ccdaad4623ec17eb72f806bea432fbe62584b512159771cb295bd273771b168f502a3a8f15588e0e9df65024271a8edb891fc48c2535e45a31289b4c3469a28 -Clang.v12.0.0+1.i686-w64-mingw32-cxx03.tar.gz/md5/2e68b66d9d607414d69bf2b11609ce5d -Clang.v12.0.0+1.i686-w64-mingw32-cxx03.tar.gz/sha512/fec58abebab5d632fbfaef8335737a54d83804a823ca6aa8ab9031aa3c2a8afd5c342d6d989d7918352c241b7d7cb8f9802a1422a44316ad0f8760998e2e02ae -Clang.v12.0.0+1.i686-w64-mingw32-cxx11.tar.gz/md5/1ab89ec9072eb7d871b3a0eff78d56ac -Clang.v12.0.0+1.i686-w64-mingw32-cxx11.tar.gz/sha512/9878561bbf405ca29e1f32049c753215ecac1bbcbb62f66dc573da3826bbdfb5f4e5630273595d611c2aa315d54fdfa35a954f71ba8781e5eb659658a9157886 -Clang.v12.0.0+1.powerpc64le-linux-gnu-cxx03.tar.gz/md5/4b8045175ede4b934e2ccc8a28920910 -Clang.v12.0.0+1.powerpc64le-linux-gnu-cxx03.tar.gz/sha512/38c952d0ed7e63c52e013e303f77c4d779ca8682926a32705402f5a275358fdd5d7f59188c0f43d994b8c2ea31939c23d0dff9a4b7312ed39574cc39c27691ea -Clang.v12.0.0+1.powerpc64le-linux-gnu-cxx11.tar.gz/md5/53ce55e158860afa17cc653f4fc0b500 -Clang.v12.0.0+1.powerpc64le-linux-gnu-cxx11.tar.gz/sha512/15738783329bca1720278526a306d230917d64d6ec6c9542a248953f5c1a071316de6bb80cd1d0498926ce876fd541d939023fda7b234ae9517f4583a2b6aa8c -Clang.v12.0.0+1.x86_64-apple-darwin.tar.gz/md5/aefdcf918b508ba66cba11abd0d99ef7 -Clang.v12.0.0+1.x86_64-apple-darwin.tar.gz/sha512/c7ef9af9bbb5a1e2fe022c3996566fe774903bee67c15dd6ae304e89fc93e5080f177ea074f9736d6959edecae415586db4dfff8328e8fdfd643019ca7d41131 -Clang.v12.0.0+1.x86_64-linux-gnu-cxx03.tar.gz/md5/490a63fadd41b10c425c1e87170b63eb -Clang.v12.0.0+1.x86_64-linux-gnu-cxx03.tar.gz/sha512/14ad28afecad4a60d0a978af75b3db68feed71badb271dee0b29bb4cb471f5e69ce85b6cc990b63a2f9db24ca87e897ee935beca532451b2ffc020d80e3cc827 -Clang.v12.0.0+1.x86_64-linux-gnu-cxx11.tar.gz/md5/9056064168e01462aae83721a670fc7e -Clang.v12.0.0+1.x86_64-linux-gnu-cxx11.tar.gz/sha512/aa0340efa8106acf92c2528c6cd5ac8b6bfd0ca0b8041e22534db4178364467dd8c46f4c77f365fa0ddeb5aefc6ed01e4a4416e1326173a255e18cc890dfc0ef -Clang.v12.0.0+1.x86_64-linux-musl-cxx03.tar.gz/md5/b4edd5baae3b1f9b18eae365d7969621 -Clang.v12.0.0+1.x86_64-linux-musl-cxx03.tar.gz/sha512/abe5ada1bfb6d69ff28fd1d16f5de3e2b12c36730f04d3fb4c9e332d4947438530f4d5a677d3dfc973769a381ec7dd1944c3ce2213bf2177d263b47b4903d186 -Clang.v12.0.0+1.x86_64-linux-musl-cxx11.tar.gz/md5/d3176f49c216d11f2113caa10020745e -Clang.v12.0.0+1.x86_64-linux-musl-cxx11.tar.gz/sha512/8585c40983ab7c401bc6537cfc3ebb7a44e52738576155855db5c51fa9c0dfbec3b5c12f63575b09c038c9f047d9941a192082ba7572489b55d5bcba2e3fb27b -Clang.v12.0.0+1.x86_64-unknown-freebsd.tar.gz/md5/1d3bb2c77b0a3473697ca2a63de35b89 -Clang.v12.0.0+1.x86_64-unknown-freebsd.tar.gz/sha512/de8922979ad7158fa72d0e152670ad3be75fabdb22a1e91d187e6847e9b6cbc905ca09a476dac651a52c775192b3bada333e68e38e6ba7101a472755bb7ad79f -Clang.v12.0.0+1.x86_64-w64-mingw32-cxx03.tar.gz/md5/ecaf6c8831e8c6de8b8e74f95f04dbf4 -Clang.v12.0.0+1.x86_64-w64-mingw32-cxx03.tar.gz/sha512/aec6626dd02fc6a0f82e05783dbce19d69a2fd9eec53189a1086393134ce1f972a1b0ef286b06f19be192fc4575d6e9f5f09984444cd3bd50c66c2fcabe23b73 -Clang.v12.0.0+1.x86_64-w64-mingw32-cxx11.tar.gz/md5/23c8b1d208dde43fe2b48f143f2108ea -Clang.v12.0.0+1.x86_64-w64-mingw32-cxx11.tar.gz/sha512/75118203f3ba67ca99279100e9b31eaff165f70af5a487bd9ad6dbf70da8041a374d9953b807739258be6e493a5422a2e5e1ba00b8ebd746b706de3915375c1e +Clang.v12.0.1+0.aarch64-apple-darwin.tar.gz/md5/9d0bd5ff9934f4d0832b89b2c896f13b +Clang.v12.0.1+0.aarch64-apple-darwin.tar.gz/sha512/1b6325b295047b4d31334dfbadabb7716e19ea1eccb809f366b06f241719f18ea54836f45d982d3cf66c4a6ae09686a4a55c76dcec1f883f0192347d6fb779d5 +Clang.v12.0.1+0.aarch64-linux-gnu-cxx03.tar.gz/md5/d3e8c671f21b15522832e80844e81199 +Clang.v12.0.1+0.aarch64-linux-gnu-cxx03.tar.gz/sha512/3b37e689aca086b05dea1b2293eb0fa8554b9c846c0ab7bb132be3600e66efb48e929e5b84a3ea1cfc9e9a3941521a395d1fab3852c9877422a1f62133fe19fb +Clang.v12.0.1+0.aarch64-linux-gnu-cxx11.tar.gz/md5/8f790f74846a5dada6a5d2db3384d783 +Clang.v12.0.1+0.aarch64-linux-gnu-cxx11.tar.gz/sha512/d8764c3f5fb5e8a3ccb93d4425145747d1e118c97beff42afc801db0189d72758b10c1ff72b9cef71e4d226065b3192710e34ecab3b988d9a27f48a88ad18194 +Clang.v12.0.1+0.aarch64-linux-musl-cxx03.tar.gz/md5/7a11f6ab531cf5e2f453145fb5f67df6 +Clang.v12.0.1+0.aarch64-linux-musl-cxx03.tar.gz/sha512/6dad060cde272417daaa7a88bca17fcdbb1f2c4ab7ac2d888e013be34d150ff5fb5c5d74a5016b9bc666c2a8d02a2b68029a51c5cb27d63ec143bcbd5f1ae4c4 +Clang.v12.0.1+0.aarch64-linux-musl-cxx11.tar.gz/md5/4ff76d1479f9e8e1462302cf1c4eb209 +Clang.v12.0.1+0.aarch64-linux-musl-cxx11.tar.gz/sha512/d295e13c0ae4eb22d499cac17dad660d47d2a4cd259295dafe33f0f9d160c0fa3a6d793fbcbe155914fd85b8fe65d44db2608e1e98d243ea08fd21abff5998cc +Clang.v12.0.1+0.armv6l-linux-gnueabihf-cxx03.tar.gz/md5/0f3945cf21990dd64da3f5a85e0203b4 +Clang.v12.0.1+0.armv6l-linux-gnueabihf-cxx03.tar.gz/sha512/45a4817d5c0d6af588264f7c996bd583c437c67924f4220256cf0c2b77662b9c42d3f3aff1a83de95cbdef76c94a079a7c2dd52585501188c865049dd0221a7d +Clang.v12.0.1+0.armv6l-linux-gnueabihf-cxx11.tar.gz/md5/8bfc3fc5bb8e71c4e8ae22a65c93e2a4 +Clang.v12.0.1+0.armv6l-linux-gnueabihf-cxx11.tar.gz/sha512/78d529f12928d950a5a6da16efe379c722628ac9647b325b7e6617623a9c809315b7e594dd9c2a12a7cd66c2a8a63956b2e0cd7c6f3ed149ba75b6300d766ccc +Clang.v12.0.1+0.armv6l-linux-musleabihf-cxx03.tar.gz/md5/3fb0f6f8be3a722b2df4cdf1d1756170 +Clang.v12.0.1+0.armv6l-linux-musleabihf-cxx03.tar.gz/sha512/72c76603c732c56c4ac0f4235a38f6be739e4f630da9f93d50a4411fce7f9995f0b86d7ff1daf60177f329ac46145c2fa7d581ebdb55c4a7f314b85633cb31ab +Clang.v12.0.1+0.armv6l-linux-musleabihf-cxx11.tar.gz/md5/b346689d4ab5757aad546521946ed622 +Clang.v12.0.1+0.armv6l-linux-musleabihf-cxx11.tar.gz/sha512/1af114292326176fcbda578a07f73c1eab90b31a0db87819bfc38c71623b3134952811390e2051466f0d48132040963fb1d93d5f121bf8fd81f58959a23c10ad +Clang.v12.0.1+0.armv7l-linux-gnueabihf-cxx03.tar.gz/md5/af253b7620b1e80772d5fd6d5d3b9603 +Clang.v12.0.1+0.armv7l-linux-gnueabihf-cxx03.tar.gz/sha512/1cbe3695204607c667a64798a9d44a6de991e5445baf4952502c8c2bc22ad0c05f17aad76d58b634015079049afec934e805dd68029aa62c3bda7e3834abdeb2 +Clang.v12.0.1+0.armv7l-linux-gnueabihf-cxx11.tar.gz/md5/0e0129a8f6d2c09a2954cbf64b9dd9af +Clang.v12.0.1+0.armv7l-linux-gnueabihf-cxx11.tar.gz/sha512/2c9bcd56f870038dd84e97cabd3861f16ee33aab99b8cf4feef9c27140ce79035394f41037f0ad8034eabf9195e22868317c74e177a68aef83b597aa67633745 +Clang.v12.0.1+0.armv7l-linux-musleabihf-cxx03.tar.gz/md5/9c245166d829cd8743a9c726a803be06 +Clang.v12.0.1+0.armv7l-linux-musleabihf-cxx03.tar.gz/sha512/c4cd7a9478b44a4a518d5ebce3d1193d4b55c2d3e107a9b949805f4669965d1fc4c6704254bd31a7c86792fe278f06374ee2c691c92d9f32ca01c12d574727c4 +Clang.v12.0.1+0.armv7l-linux-musleabihf-cxx11.tar.gz/md5/53686f336daa4d76dde90bbc0324635e +Clang.v12.0.1+0.armv7l-linux-musleabihf-cxx11.tar.gz/sha512/20ac50b52bf80edc6a729e513577f295e7b89a8aca3d618bd323cf0c44d2313e49e9549ade36100855345291425ef966ddd342c456ce26ea777a0b82ac837551 +Clang.v12.0.1+0.i686-linux-gnu-cxx03.tar.gz/md5/4e5fcb61d9dea624dc30df1c6ea3e7ad +Clang.v12.0.1+0.i686-linux-gnu-cxx03.tar.gz/sha512/30b407d5420fd0b3da4a82cc5e1b1e7a8c1764793ca3e6d6c0dac9bbc212d67d95037ef8a6fce282299f9a3232371e410e2c8942f1b5958ecedcc8879e19ecf6 +Clang.v12.0.1+0.i686-linux-gnu-cxx11.tar.gz/md5/70fd7d0b22447a1e1856bae3e58de0fc +Clang.v12.0.1+0.i686-linux-gnu-cxx11.tar.gz/sha512/4e2446c562834e308697135ec775b1d28119822c7a0028249c19ae9e495ed216d8e135781bad5ea722322dc5d24b725439cff9b4af8555b24886008690a574c2 +Clang.v12.0.1+0.i686-linux-musl-cxx03.tar.gz/md5/e30ae623bfd0c7af72d6ddd87343d3e6 +Clang.v12.0.1+0.i686-linux-musl-cxx03.tar.gz/sha512/df9982ff7d83d9e25ec796d3de2a22d8bdf34d463d9dd0b4ed65289a3295235dffc621efe100408f7fced05c611dd44c74fbc4599ff0a4fc19d22fc305fcc2c0 +Clang.v12.0.1+0.i686-linux-musl-cxx11.tar.gz/md5/a4bcb55a537e553a0e95392e924aa46f +Clang.v12.0.1+0.i686-linux-musl-cxx11.tar.gz/sha512/6747a2b607caf0606d4c5ea06f0c23fe39d8c31310bb773f18ff8a0e8e9a9b79e745f5d5d1c9fc69adcd1f3561020814e3088a693acf124662b81b8e92651455 +Clang.v12.0.1+0.i686-w64-mingw32-cxx03.tar.gz/md5/a513038e7b0849ed6daf1609ce5bfeec +Clang.v12.0.1+0.i686-w64-mingw32-cxx03.tar.gz/sha512/3acf8c08b04137d5271cae03085eda859a1b3c519b9540d627d2b05581964234523d2bd3233bf59651f306f1cfa7e5862792503ceda39f0981ab25ced12b9ab9 +Clang.v12.0.1+0.i686-w64-mingw32-cxx11.tar.gz/md5/11214b74d6b50c68a5e5e7e21a9b3787 +Clang.v12.0.1+0.i686-w64-mingw32-cxx11.tar.gz/sha512/ba7c29fc008a4b0c10530383ab30c0b2bb60f3572d471ded7089bba088163a05fc06af310931f12b057a8a932914bc6a0e0efd3f9832ae52a34d3cc066486874 +Clang.v12.0.1+0.powerpc64le-linux-gnu-cxx03.tar.gz/md5/7802c4438fc9d83bd456cef8eb1bc2d9 +Clang.v12.0.1+0.powerpc64le-linux-gnu-cxx03.tar.gz/sha512/a24796700d12f15c827a43acab0b8bf9afd0f68ee32b4b98e8aa5d3df152f46230b13f072d50ac25986fde79a822ee78d595f8d1c28cff168e89a4e15d5cbd09 +Clang.v12.0.1+0.powerpc64le-linux-gnu-cxx11.tar.gz/md5/bce9c20a48ea31265d3a57ecc598c146 +Clang.v12.0.1+0.powerpc64le-linux-gnu-cxx11.tar.gz/sha512/d35d2d1efab91fa2e7e244bb4dc9811adaf01cb42f448abf0ee688381959c304a5cc4ae5fceae9ed60a2b0d34dcc795b8dbb405b1f770e7e05a3d16962d97f99 +Clang.v12.0.1+0.x86_64-apple-darwin.tar.gz/md5/cddf72884b50d35dad7173625285d2a9 +Clang.v12.0.1+0.x86_64-apple-darwin.tar.gz/sha512/638dbf23827b7486a90ef5f1d79419a7c09411d4f8ad8da5fd20691d38185c28b5aab5b9a2acc43a4e596b831cd27eca489efe79e007f7540f98cd563eff8624 +Clang.v12.0.1+0.x86_64-linux-gnu-cxx03.tar.gz/md5/86c8206b2e38d5cb7365dfcd50d1f027 +Clang.v12.0.1+0.x86_64-linux-gnu-cxx03.tar.gz/sha512/60d5e9db3d3bf4d8309e462b6d47b258433cd77fbdebfafb7c5f07ec4bf2408e61f645717c260a5c4be150fd86905174b9a806b194a153883bb16590b33a623b +Clang.v12.0.1+0.x86_64-linux-gnu-cxx11.tar.gz/md5/83a0d75a072631c856ed2110acf8e444 +Clang.v12.0.1+0.x86_64-linux-gnu-cxx11.tar.gz/sha512/908fabecef669ba579bcc59e911b68ed8deb5b3bda49d0dff6ae01dfa44526ebca81e83238a1abaafbf6b249e56409652eec304e0e82cb056d6182dbff9fbb2d +Clang.v12.0.1+0.x86_64-linux-musl-cxx03.tar.gz/md5/8ba30a11ea311716ff27cc7631837f9f +Clang.v12.0.1+0.x86_64-linux-musl-cxx03.tar.gz/sha512/3bace26a82809153826ecafa440e563576178fa0481c754d5d0b8a3c60cd0caf5d4db8f8c860fa0779bae768a5a6f4427951baa00588713c19328212662700b9 +Clang.v12.0.1+0.x86_64-linux-musl-cxx11.tar.gz/md5/c7ab6f58f6de37432b87c6f8607fa455 +Clang.v12.0.1+0.x86_64-linux-musl-cxx11.tar.gz/sha512/1d9c9553710f0a7453a6d53b0529fd08782825870bac4074f55a2206c5f7372ec8578a951978f09aaccf481919096f4c4f16db4bb1ae707594b747402cad8213 +Clang.v12.0.1+0.x86_64-unknown-freebsd.tar.gz/md5/1aad4f620028b50ebb9b537f57fb5c48 +Clang.v12.0.1+0.x86_64-unknown-freebsd.tar.gz/sha512/0dfc1e8d2dfbe481848f15b543dc1f22d43ca8a83ca4cfc870faeef046453ece621a866c1dbc384c58aca11ff607cc14e77c64438ca2f3402ac78c268671af8a +Clang.v12.0.1+0.x86_64-w64-mingw32-cxx03.tar.gz/md5/2d0b4f4f249d7e910b3566c9fe8253ab +Clang.v12.0.1+0.x86_64-w64-mingw32-cxx03.tar.gz/sha512/e95329f809489ce64ba34e6c9bf773f6b5be0e69250bbcd45df995b7a88f4583339be3e9c1e353740e5047954b3a553b1a76bfd40ede5fc23b3504ec6dee91a2 +Clang.v12.0.1+0.x86_64-w64-mingw32-cxx11.tar.gz/md5/8d7178a3c1aae01a39a56c7b80e3d584 +Clang.v12.0.1+0.x86_64-w64-mingw32-cxx11.tar.gz/sha512/6a838935a32c36c106cd105d3e0a8324c020dc400446a11d3b4dc266cd30b31eda1f26215429607377c332e989085331f6886ff2e3ec990711ae836eabe0498e diff --git a/deps/checksums/llvm b/deps/checksums/llvm index 71b445c82f00c..a865392ba8f72 100644 --- a/deps/checksums/llvm +++ b/deps/checksums/llvm @@ -1,242 +1,234 @@ -libLLVM_assert.v12.0.0+1.aarch64-apple-darwin.tar.gz/md5/9b6a02cdb753464998c2108401321c8c -libLLVM_assert.v12.0.0+1.aarch64-apple-darwin.tar.gz/sha512/4986a37bdfebb17a2c70f3e24dc104a2b9c48fda5149e1e8f0df1b7139689e09bc6f5438f34e3fb6ca1ccbae57792959e2ca6fe66b267a2081df6a999cc11d35 -libLLVM_assert.v12.0.0+1.aarch64-linux-gnu-cxx03.tar.gz/md5/4e6d298d5680c3a063739f508561e357 -libLLVM_assert.v12.0.0+1.aarch64-linux-gnu-cxx03.tar.gz/sha512/c70ef95a4e3c571b119f8d623b17d98591d268f7242c024e33b87ff80dc6cf96a7589c5e4e528d4f3b54fb8c7b1b6653873b4ec7a94b297524b9fda31dded006 -libLLVM_assert.v12.0.0+1.aarch64-linux-gnu-cxx11.tar.gz/md5/941d910dbfa4f7339c942f547596daa3 -libLLVM_assert.v12.0.0+1.aarch64-linux-gnu-cxx11.tar.gz/sha512/486a01f9c8f632b6f84d802b00c443cf9a5fbcca61ea7cc392c9211c71243e39f50ae8812dde7f5347965e0aa9a8dbd73a4988d780ae77dfa04fe329359c50dd -libLLVM_assert.v12.0.0+1.aarch64-linux-musl-cxx03.tar.gz/md5/ab8f2a3167d192a933c86214c275d1e9 -libLLVM_assert.v12.0.0+1.aarch64-linux-musl-cxx03.tar.gz/sha512/fec5e2ea1398c226cc9a3c31c5041f9b4e111793039f7cc373ff47e86e72685a4cc254ef3d42db7cee239a7422f56fdba513f572f5156f8dd6c286c799547636 -libLLVM_assert.v12.0.0+1.aarch64-linux-musl-cxx11.tar.gz/md5/dce59160064ef20720e2b97e903dc829 -libLLVM_assert.v12.0.0+1.aarch64-linux-musl-cxx11.tar.gz/sha512/704d2007d0074a87a2c780e6b9f38117cee75a9e3e7a84edb9915962d7d5dc92453dc8ad3f2a73404173b7cdce5759f7764011452b9dd0da71053fa87bf89be4 -libLLVM_assert.v12.0.0+1.armv6l-linux-gnueabihf-cxx03.tar.gz/md5/e8e483bea9effe1a43cb14eb32d2edce -libLLVM_assert.v12.0.0+1.armv6l-linux-gnueabihf-cxx03.tar.gz/sha512/709e10ae71641ac285380a73457988df8745d9baaa1584ef67871daa42ef16b568aa93633f774a9d4541ed1cefe49c7614b295f16da6fab91e493a2a58ff7143 -libLLVM_assert.v12.0.0+1.armv6l-linux-gnueabihf-cxx11.tar.gz/md5/2ef8f91e7df587e2bd8c73140c29d771 -libLLVM_assert.v12.0.0+1.armv6l-linux-gnueabihf-cxx11.tar.gz/sha512/6b16d86a6636b070924d251581ec01df759197e642f8703111869c2510194b40e3dd6d56e605208d9e4d1a0fbe96709d56a9d065f3111979c989cda9c44093f4 -libLLVM_assert.v12.0.0+1.armv6l-linux-musleabihf-cxx03.tar.gz/md5/7ae9c70790aca9cc9ed2dc6504f44348 -libLLVM_assert.v12.0.0+1.armv6l-linux-musleabihf-cxx03.tar.gz/sha512/4d5aaedf590343bb788d6a8cfd714d3d659a82e44c411d93bcd8f524bd0563dc8ac2ddfafe87b2c762e7d9f22a1bc6cf7a331343738e7a38c246f41a8bf24d64 -libLLVM_assert.v12.0.0+1.armv6l-linux-musleabihf-cxx11.tar.gz/md5/2be0d9c87322bf63d3081e434b3b5eda -libLLVM_assert.v12.0.0+1.armv6l-linux-musleabihf-cxx11.tar.gz/sha512/45bc193f86093e479710455ac7bbd4e853537e2d22946a4c30d942a3f2f1946b2156fd80282f05a3fc73a65835d06d372b76ce90685cb4f1ca31606d2481b1d6 -libLLVM_assert.v12.0.0+1.armv7l-linux-gnueabihf-cxx03.tar.gz/md5/7009d45f00f0ce67ffca15a59ae0b682 -libLLVM_assert.v12.0.0+1.armv7l-linux-gnueabihf-cxx03.tar.gz/sha512/5030c05e5b91d1fcaa866522ebabe0f112493fae9aa64cd3a003266939093bb422320f2cad31c19ee1989f5beb84781b1b54090b6a4c2a8fda3e80809ae65160 -libLLVM_assert.v12.0.0+1.armv7l-linux-gnueabihf-cxx11.tar.gz/md5/cd92d0ea3f9aa34c834f6ba9c5d6b199 -libLLVM_assert.v12.0.0+1.armv7l-linux-gnueabihf-cxx11.tar.gz/sha512/b79e5f42890712e2ced99e80e1827aef0824568c34f029ed94142a29b925375a8e85d305411e42d05bee1959863906f1958485b3fb982b022cf567871005e20e -libLLVM_assert.v12.0.0+1.armv7l-linux-musleabihf-cxx03.tar.gz/md5/406cc9431dde64b98b7c2cf0d44b8528 -libLLVM_assert.v12.0.0+1.armv7l-linux-musleabihf-cxx03.tar.gz/sha512/426a99f9b4eac3835de4a1ae3f49a23c342f773af5a3c4c6354cb27a120f8d83513ac9dbdcd1040b018ffdf6f5092de66fb37a8eacb07b9eed67a1f6da411fe1 -libLLVM_assert.v12.0.0+1.armv7l-linux-musleabihf-cxx11.tar.gz/md5/c6d6c5e91e33fa326763034b58c9c306 -libLLVM_assert.v12.0.0+1.armv7l-linux-musleabihf-cxx11.tar.gz/sha512/7b2557c766371fc12172ac6469624fd7452e2be49c0ee4e0658018e1e779122d89cdb81fddf8df1374ad17286b96e299320d076b2527137680423bcd3a88e5ae -libLLVM_assert.v12.0.0+1.i686-linux-gnu-cxx03.tar.gz/md5/8f3acc592c604ea386488a28c12a69f6 -libLLVM_assert.v12.0.0+1.i686-linux-gnu-cxx03.tar.gz/sha512/049d11ea4d44a60037c25c8893a336358f2422a4ed7d350f0212736b040b7af2d50fb80681d20ff58c220f9bc4559cc2b70ead1efa923cd0a36b12f3673f343d -libLLVM_assert.v12.0.0+1.i686-linux-gnu-cxx11.tar.gz/md5/9727f0bd0663847095a8f4574a87c318 -libLLVM_assert.v12.0.0+1.i686-linux-gnu-cxx11.tar.gz/sha512/0d3a344b37cc4345d31612964f95674b18d2d41dfb6314d12c88290772bc9ed5d15dd90c2e8940710c1accefa368046c626d12c42297de162e24f08653ef2a6b -libLLVM_assert.v12.0.0+1.i686-linux-musl-cxx03.tar.gz/md5/9bb55b1d0e0e52443296b96b2117b6cd -libLLVM_assert.v12.0.0+1.i686-linux-musl-cxx03.tar.gz/sha512/02450ebbd012aeac1e86ce22ce699dc0ebe75748335ab37ef854d3ff27d08e5762a1addf400e51aa26dda44f16c93e7b16199cc6d8e4019736bb0138044693cf -libLLVM_assert.v12.0.0+1.i686-linux-musl-cxx11.tar.gz/md5/f7bc96ec83a87233c3eaab79f117f9b3 -libLLVM_assert.v12.0.0+1.i686-linux-musl-cxx11.tar.gz/sha512/c398b9684ea06e1cf4595c30eea69bce0623f858647ff686a6592d6d062479cd1ae4bb01367f7ef156ed75457454e6f4df7bcaceaa2f3f50ebdbfe2777f326d0 -libLLVM_assert.v12.0.0+1.i686-w64-mingw32-cxx03.tar.gz/md5/b495bf59b53148178937ead404f887f2 -libLLVM_assert.v12.0.0+1.i686-w64-mingw32-cxx03.tar.gz/sha512/ec5e2316b846e436024c16aec6a271f23ad7879119660488509e3a88e8012e1b1592f492696d645b7ec5b2d710c9524100a186df836ff03ed9b8728b009a381f -libLLVM_assert.v12.0.0+1.i686-w64-mingw32-cxx11.tar.gz/md5/57e237b29d01266c97c2dc716f8648a7 -libLLVM_assert.v12.0.0+1.i686-w64-mingw32-cxx11.tar.gz/sha512/742eeba173b2ad95b8ac9ba3b21afc49a081aee6ed12607d1e17e648310372dc95c5f839cac8db74a49a0eed8b82700922176b55a57b3dc9ee4a820da9816283 -libLLVM_assert.v12.0.0+1.powerpc64le-linux-gnu-cxx03.tar.gz/md5/5d1c3f5cbf94df631b7f1a73a0a2063a -libLLVM_assert.v12.0.0+1.powerpc64le-linux-gnu-cxx03.tar.gz/sha512/8072be35d0ab07d853815ccc84013f76895603297bb4f4b77b22fe538467b273a6e6918486db8170f7e2ba2507b5e36ef42f9f321c797ac5e871618d3372ce66 -libLLVM_assert.v12.0.0+1.powerpc64le-linux-gnu-cxx11.tar.gz/md5/5d1ea307a7481ca0393f88f3929de53b -libLLVM_assert.v12.0.0+1.powerpc64le-linux-gnu-cxx11.tar.gz/sha512/c62e3f7807390144f65cf9081b3f6710c1022f260a2ffda0d7e72583224cac638e87655d472de2490ce465279d79edea18a6fea99b6afbbdd9a427ef5d6439ad -libLLVM_assert.v12.0.0+1.x86_64-apple-darwin.tar.gz/md5/f7764a7eb7bb79439bcc8a853dff5b22 -libLLVM_assert.v12.0.0+1.x86_64-apple-darwin.tar.gz/sha512/b1cdc7f1078eb07e2d37482c96b14c288f6c0d5c0860854e02c3c1a407fcb66d4f03abccf1b74b7ee9a6eb503b3c60e67e7ed75ece765b385f17c6f502a5d489 -libLLVM_assert.v12.0.0+1.x86_64-linux-gnu-cxx03.tar.gz/md5/99a5965cc849e3dd79878a7c6b29b6df -libLLVM_assert.v12.0.0+1.x86_64-linux-gnu-cxx03.tar.gz/sha512/9b138f955de9266ff364022f53b6b8641670a8221e0bb6b61d5bbc9151e8c4ce08c61fcb90d6572c51853723f53c6b6afebc5c4e17e6e33e39590c53c5206f91 -libLLVM_assert.v12.0.0+1.x86_64-linux-gnu-cxx11.tar.gz/md5/2a27b02a388679164b58dbd853f5145a -libLLVM_assert.v12.0.0+1.x86_64-linux-gnu-cxx11.tar.gz/sha512/febee5224a7e4499509105c59365eca340526e002f12395bfb2a31c944fdaf89345fec971c67874356c8235abd14bdff3d7485c13bb4af944105dbb43b2d665c -libLLVM_assert.v12.0.0+1.x86_64-linux-musl-cxx03.tar.gz/md5/f23b627174133dd8e94733c6bef0ac89 -libLLVM_assert.v12.0.0+1.x86_64-linux-musl-cxx03.tar.gz/sha512/b7b2fdc4d154b2e1aa805a98d6b15c6a88a1dd59812dba1030ca0628192b993c965ccc7e0aefb723ce6ce8ecd3a6788fdd0cdcdc5c966bef55f67834b056e52b -libLLVM_assert.v12.0.0+1.x86_64-linux-musl-cxx11.tar.gz/md5/0dbab594b2066ffdcf4c1fe47612cab1 -libLLVM_assert.v12.0.0+1.x86_64-linux-musl-cxx11.tar.gz/sha512/86e4d06a6c52d04175d8751cd84cfe1896ac66614aa92c7d60674a3ba49aa6a68e9700cc8150abecc7acdae4786d9899eb052a015a902a2459858156b0ffc2cd -libLLVM_assert.v12.0.0+1.x86_64-unknown-freebsd.tar.gz/md5/5b39f69421ab3c5a234436a7b8430c82 -libLLVM_assert.v12.0.0+1.x86_64-unknown-freebsd.tar.gz/sha512/2dc735103c4c4eed676a149ddb8d4959ed8c6c00698683b5213d22661d5a1c079fdaf2c21196bf5d4e3841692bc09dfc4c8b723d808b33b94bb06a407a8ad809 -libLLVM_assert.v12.0.0+1.x86_64-w64-mingw32-cxx03.tar.gz/md5/21bd6a1e696b015a880efd795fa0e136 -libLLVM_assert.v12.0.0+1.x86_64-w64-mingw32-cxx03.tar.gz/sha512/218bf452d5336d1ed69879b33f50f92f0118fefe21366733746cf50d6accd7b0ce71659233470f1f3eff26180a5245550b2c53b2678ded317bfd0a5c2a4fc2df -libLLVM_assert.v12.0.0+1.x86_64-w64-mingw32-cxx11.tar.gz/md5/cdce26125c4f37ee3c9f92cdd7598da5 -libLLVM_assert.v12.0.0+1.x86_64-w64-mingw32-cxx11.tar.gz/sha512/9bed9f8b1fc7f94f67aa5d2496a5081ab594d3210b93e5ee1f71e32bb053e87229afd783d34c8d048afbd396451c75c82b7c7d5f60d018b7325f703687eaa07f -libLLVM.v12.0.0+1.aarch64-apple-darwin.tar.gz/md5/4ac10ba89a464473457448f2f697abc0 -libLLVM.v12.0.0+1.aarch64-apple-darwin.tar.gz/sha512/ee80c94d8a4c89910d170a9781f72bc53e0b3e3b853157d0830b16626ba7d188d4a3c1c7b723c4c4d428676e4f8c3120928dc7b59a5f950d096d25b5d488ed31 -libLLVM.v12.0.0+1.aarch64-linux-gnu-cxx03.tar.gz/md5/95500f6f9eef53d670fd77a6949d43b0 -libLLVM.v12.0.0+1.aarch64-linux-gnu-cxx03.tar.gz/sha512/e3099e8587aa36785fc48d05691236c62c7121c953f645ac5fc7d9068127c8bc7e3aa48f0a1ec8a994c3729f75ae3bf155baaa4f1c7e761860e38d7f89d29117 -libLLVM.v12.0.0+1.aarch64-linux-gnu-cxx11.tar.gz/md5/a900d9889fc22a19e005e550f0154709 -libLLVM.v12.0.0+1.aarch64-linux-gnu-cxx11.tar.gz/sha512/acc1bc5338d8ded0898818fac5b3a1e0528df3902ae9e4062ce2db3a769ead7168ee152262ad98cfada19941f9c49a72fad7e356d1b7f046bf0a05db83af3f9d -libLLVM.v12.0.0+1.aarch64-linux-musl-cxx03.tar.gz/md5/4d62b2d7e0de328a8f1d497acd9dec4c -libLLVM.v12.0.0+1.aarch64-linux-musl-cxx03.tar.gz/sha512/6c199d25f038bb619e8c7449d65dd61be4d264109acfe5e694881bd7ae7d207cc714bf3350442c27a73a0d3702a5ab386c90ac6c7147b3b0b7de862f28584e74 -libLLVM.v12.0.0+1.aarch64-linux-musl-cxx11.tar.gz/md5/52af995cd60019b0fc607f7d89d1db73 -libLLVM.v12.0.0+1.aarch64-linux-musl-cxx11.tar.gz/sha512/98c412b6ef5d12f6a0fbf2b9a848a3e26ec98f9eaafa9c7048d52164df69716aa2ce172e546c56627d208e9aff03f1fd0b011eeed842cbc92280bda5c42e1e5c -libLLVM.v12.0.0+1.armv6l-linux-gnueabihf-cxx03.tar.gz/md5/ba0a2f3e9ba09b2081062437d12c3b58 -libLLVM.v12.0.0+1.armv6l-linux-gnueabihf-cxx03.tar.gz/sha512/a4f5a47a876b660c1d08805ce296ae59ec65dfa89334542cbbdd696909b2be8697b104006f365ea404c2967928dd5580bd2c7d9a03f3894952742456f450415a -libLLVM.v12.0.0+1.armv6l-linux-gnueabihf-cxx11.tar.gz/md5/d2c4da0530fea40e082404886e86caf7 -libLLVM.v12.0.0+1.armv6l-linux-gnueabihf-cxx11.tar.gz/sha512/a66ec214d80023110e281b2029d9dc8ad61a1a3be9bba96ed7d5bbfcacba76d7359c152982036d317d383a390e27a6eea969d6bd5fc50ef7b879dccac5dd320c -libLLVM.v12.0.0+1.armv6l-linux-musleabihf-cxx03.tar.gz/md5/abd5d1cd535566f61ff0138ca852b771 -libLLVM.v12.0.0+1.armv6l-linux-musleabihf-cxx03.tar.gz/sha512/f247d4127798576e0a39cb2b78c359c30679b2f5ade08a39973989fbd72387a06ef35b3421c4ebde564240776a4be9b3a24f78eebc22ea192e72941558264093 -libLLVM.v12.0.0+1.armv6l-linux-musleabihf-cxx11.tar.gz/md5/abbe7e449a3a0d78ba320b0cf9b98534 -libLLVM.v12.0.0+1.armv6l-linux-musleabihf-cxx11.tar.gz/sha512/8b2b50d972d76b18938856546f7fa13b243cffb348f64f0c528668c1ad6e28bb03f3af05fa5af8ca01a4cb12062719665fdce6018c6141ae7bdeef1cb876351a -libLLVM.v12.0.0+1.armv7l-linux-gnueabihf-cxx03.tar.gz/md5/a5d0b33472dc32278cacc0b5904aa569 -libLLVM.v12.0.0+1.armv7l-linux-gnueabihf-cxx03.tar.gz/sha512/501f6a43cd75f33056723781becc40fa1babab2a0e720700bcf4708782cecff20140d753141de8a2bf06fa8d97360b9e7533a3947a5eb39453fca5ba6d94fd15 -libLLVM.v12.0.0+1.armv7l-linux-gnueabihf-cxx11.tar.gz/md5/b9f62938d21eef15bf58b799d06f049e -libLLVM.v12.0.0+1.armv7l-linux-gnueabihf-cxx11.tar.gz/sha512/6430c18e13c7f97c2b12594d6ec0afee9ffc8fdd0e1608a40df79345932b9739bfd8f7d15b494bd576784b12b4a1400c9fdaaeb350f74bf2f15a3dd66bea4d4c -libLLVM.v12.0.0+1.armv7l-linux-musleabihf-cxx03.tar.gz/md5/c87fd44a812346a6c471a7992c1898fb -libLLVM.v12.0.0+1.armv7l-linux-musleabihf-cxx03.tar.gz/sha512/f00d6caafc3298ac8fd7ecff937e453c97e41167dc2e0f43abf83cf6b899380d1db70e74245ebcb1bba8022e0f86d30dfae214005dc6b02232b0bba6045ddbca -libLLVM.v12.0.0+1.armv7l-linux-musleabihf-cxx11.tar.gz/md5/260f3e0ed2bcea0122f4c104cf115661 -libLLVM.v12.0.0+1.armv7l-linux-musleabihf-cxx11.tar.gz/sha512/3a853ca386e8cf578d92ec55c824e0e1b6ef8551dfbd4bd042f81e3063fc9a1bd25a3a3b182444e178e34c4a477bc4293a3b4ab1eea1915f9c063c396c548ee4 -libLLVM.v12.0.0+1.i686-linux-gnu-cxx03.tar.gz/md5/eedcb1470ba914c6df43d41aab2f336e -libLLVM.v12.0.0+1.i686-linux-gnu-cxx03.tar.gz/sha512/4634c7bdcb1a7ec31d7f629da1418dbf7c2da8ef35c59daa8acde5ddfb04acf617e60368c1ddf21d7ce3684f0d091471264107a3674ac7cb8eccf05e8d7ef82f -libLLVM.v12.0.0+1.i686-linux-gnu-cxx11.tar.gz/md5/26854ac7b1d8b5cc516310c6f0603e28 -libLLVM.v12.0.0+1.i686-linux-gnu-cxx11.tar.gz/sha512/2579b123cbfd7f306747ea0eb9830228b330c2443153dcee3d97388465c974cc1b67ad729a5be8519c31e90a85221c03c56dc244a202a190cc9b54b1e9b4bf09 -libLLVM.v12.0.0+1.i686-linux-musl-cxx03.tar.gz/md5/844eb964e50bdcca7c7c046bc3f7be99 -libLLVM.v12.0.0+1.i686-linux-musl-cxx03.tar.gz/sha512/da0f995f96f060933f828a38c1d1b586ee5ec9a97f22626fb6297d1da7c9be4a79fb17b5207f51e96b0454c9684bd7c371a0f43585e135ccc28d873ca9215649 -libLLVM.v12.0.0+1.i686-linux-musl-cxx11.tar.gz/md5/b3ab85c5a4d2aee0aa07d75e49d35f88 -libLLVM.v12.0.0+1.i686-linux-musl-cxx11.tar.gz/sha512/b1656422f172685ebd8ef090ecf4c06f7364612f4b195820d2782d5252dc965322b66ae3f0d42817685a12ba2460e66ea201bf2bf5e48199156c4f124862097f -libLLVM.v12.0.0+1.i686-w64-mingw32-cxx03.tar.gz/md5/619ef68aad7d051b32777551b6465432 -libLLVM.v12.0.0+1.i686-w64-mingw32-cxx03.tar.gz/sha512/fdedb19322bd216d6aa4908afbc99b0789424c6b27d6be7769c9b1b80e35ae04b3da290d7a5002bf95bee725684d5c8303b3fb762807cde5b5451b5a107a6e5d -libLLVM.v12.0.0+1.i686-w64-mingw32-cxx11.tar.gz/md5/9a62570aaafc78a52bfd0799ef27d38e -libLLVM.v12.0.0+1.i686-w64-mingw32-cxx11.tar.gz/sha512/3b629bb4611f6ec388c4ffd03f2456780f41528f6f99446f2a0adb35c1953921641d2fffed5224817dfe76a6faad832a11267e57b01469959242ab34d1b1823f -libLLVM.v12.0.0+1.powerpc64le-linux-gnu-cxx03.tar.gz/md5/fea7ed9b9d20e76d2fe31ca3e5cfcd3a -libLLVM.v12.0.0+1.powerpc64le-linux-gnu-cxx03.tar.gz/sha512/5448b21d8746f15c8c496b2123963c4bab271770003bad45150e93d6dd69651b604720bfadd5fe95a9034cf5bceb41c2f85efb0bd3420bc2ff0c0e100a51f10b -libLLVM.v12.0.0+1.powerpc64le-linux-gnu-cxx11.tar.gz/md5/04700344e64312cf3d8e0cac982e8a33 -libLLVM.v12.0.0+1.powerpc64le-linux-gnu-cxx11.tar.gz/sha512/f89b350716508a9278ebc64cadc6cac0f7bcf76e966facfa6e8713103554806d8d788d2a8bc8ad7f8c21d5ddb3e943fa11db9cf51aa24f92302d4f592fa5a601 -libLLVM.v12.0.0+1.x86_64-apple-darwin.tar.gz/md5/37dd7c11c6533af26774c8d60f47b944 -libLLVM.v12.0.0+1.x86_64-apple-darwin.tar.gz/sha512/793b04f255546fc76158b21c1e8018700416341199c2681a14a3bd28f9799fe2e7bab40b05421e6bbd9bd08608af3db705e14d1fa52f213821a8a80c69d2ccdb -libLLVM.v12.0.0+1.x86_64-linux-gnu-cxx03.tar.gz/md5/88b02af758c3373c026f6c727431a1aa -libLLVM.v12.0.0+1.x86_64-linux-gnu-cxx03.tar.gz/sha512/eb29edd8b35417adcbd400fa5c0327d5c03ca014e6699330d08488c4d83d10aeeb21b60acfc51f5fc05c9fe46a048edd12702790cbd731db653d06b1746e5650 -libLLVM.v12.0.0+1.x86_64-linux-gnu-cxx11.tar.gz/md5/c3c759d8706cc339077d2f084f36d6c7 -libLLVM.v12.0.0+1.x86_64-linux-gnu-cxx11.tar.gz/sha512/595edb80d42b47835ae435526711ec3fae39d12fcad28e1c2abdfb3dd414f71c7ac3e1ac5ac16c25e7e1c0885c6591358ed066d9be0d701c17d155fbc0f9f701 -libLLVM.v12.0.0+1.x86_64-linux-musl-cxx03.tar.gz/md5/5e297c6897cf1bc9e0d5627a31295473 -libLLVM.v12.0.0+1.x86_64-linux-musl-cxx03.tar.gz/sha512/3a18eb2fb891071516fec4340809eb511369f70674c96db02558ea07f3819680f4f63cf20fd57a76293ed9c18746b3c2572cbd1b1621721142e7c4526294baf8 -libLLVM.v12.0.0+1.x86_64-linux-musl-cxx11.tar.gz/md5/a3f0facc8ffe1a806f38a7441e307be5 -libLLVM.v12.0.0+1.x86_64-linux-musl-cxx11.tar.gz/sha512/751a55ac5ecbe328097998c6a9c57198cf326bd5bbbadcdfc3abdcdbf6802b4a039df8a6a5020fea911fabff7eb113207e87d4fa1a7debef59832d5aa9e10846 -libLLVM.v12.0.0+1.x86_64-unknown-freebsd.tar.gz/md5/2728fc4d132e5f6e955ca684c75dc021 -libLLVM.v12.0.0+1.x86_64-unknown-freebsd.tar.gz/sha512/64b28ec60e564d815f3554f363e70770cec9936264ec5c3022a422acfff836aafce0d7bd3a83819735fec203f62af43e84f8770b89784f3a8e71890d1bc900a3 -libLLVM.v12.0.0+1.x86_64-w64-mingw32-cxx03.tar.gz/md5/82abd763588375fa58700085edf4d1b8 -libLLVM.v12.0.0+1.x86_64-w64-mingw32-cxx03.tar.gz/sha512/89de803c913967c087851197d18f2ae9d6ea10c653b3988ab77edd1a90b94073fe2477f4291f10fb9496dd5c77c952e7358f68788d487989fb164001b6522d41 -libLLVM.v12.0.0+1.x86_64-w64-mingw32-cxx11.tar.gz/md5/6805ae4e8276b1e774decc8d755b518a -libLLVM.v12.0.0+1.x86_64-w64-mingw32-cxx11.tar.gz/sha512/002bf892daa13ce1200996035ad7159d90c5f5974989c5c20a4ebc74c0f82553a2d0198459dc4ee7f7363cc3d10e5b11bf7088bd1288af9fac0cce707de8452c -llvm-12.0.0.src.tar.xz/md5/ceab21c9081e122a88d82216a80d0dc0 -llvm-12.0.0.src.tar.xz/sha512/ec17153ef774a1e08085763bda7d0dfce6802fbaa17e89831695ce1b2eb015a6c2aebfaa9fe7985a83b9c51bd75d40bb4f1fc706dc16d4c0dc2b2722a1d8a24e -LLVM_assert.v12.0.0+1.aarch64-apple-darwin.tar.gz/md5/a6ac9c9c1831bf01edf1bcb526e7c62d -LLVM_assert.v12.0.0+1.aarch64-apple-darwin.tar.gz/sha512/4473ba37065329cf91192c0496136f161030da03a9a7e72106f41403e5b49debe7f0c203839f7deac7ca0b61b3d136404bf442b4f044f10e636a994e34994a40 -LLVM_assert.v12.0.0+1.aarch64-linux-gnu-cxx03.tar.gz/md5/0ccdf2fadf185c90e1938d946a6542e3 -LLVM_assert.v12.0.0+1.aarch64-linux-gnu-cxx03.tar.gz/sha512/d35e314b2928ce16b0369c1b7b38682d42d1443e0ca72f77e1b32d2231af5dc5a66eaee1881832ade8777566a0447319805e8fc1f2b702b19097240ac36da1fb -LLVM_assert.v12.0.0+1.aarch64-linux-gnu-cxx11.tar.gz/md5/3acde3cd87feb3984f45f0ef323002e1 -LLVM_assert.v12.0.0+1.aarch64-linux-gnu-cxx11.tar.gz/sha512/be8d40794a5eee7ea775e33c8173deb3a775e5eaebfdc20341ad66a6d12d48692e0838e872245c74a8bea46ca085f8f3e7995f6ba33df2444fdf79d251ee272b -LLVM_assert.v12.0.0+1.aarch64-linux-musl-cxx03.tar.gz/md5/760edd92d241365409c59ca9ba46ce6c -LLVM_assert.v12.0.0+1.aarch64-linux-musl-cxx03.tar.gz/sha512/45b52ec2f516a7098f89f6ca6027d677329780ce61886821478d6889b1b1624d7f43e6f23daa2037c4fdbb25a71f97ef5a1ad9e0574760f0f304a2eb01cf6793 -LLVM_assert.v12.0.0+1.aarch64-linux-musl-cxx11.tar.gz/md5/907174cef57551c44825034487417b31 -LLVM_assert.v12.0.0+1.aarch64-linux-musl-cxx11.tar.gz/sha512/5abac8be17a83108ce3bf0c6d48342cc5db506049623c35859045758a3c31829bf388fc9c6ecc2ad1438e464930d9e1870cadc895eb7dbc72bdafd04666f60d7 -LLVM_assert.v12.0.0+1.armv6l-linux-gnueabihf-cxx03.tar.gz/md5/f90b16fffb796299a4e061d302a9855d -LLVM_assert.v12.0.0+1.armv6l-linux-gnueabihf-cxx03.tar.gz/sha512/cc3f019f88f167ee45638e3bf23f04ec8e4b021000e53342189bd75a2145f99523aa501e60457fc5cbbf5d35e1f8fd17a97fa9b18ebed5a04c2366333094e440 -LLVM_assert.v12.0.0+1.armv6l-linux-gnueabihf-cxx11.tar.gz/md5/3aa7211a765fe31a56d48151b7ec820d -LLVM_assert.v12.0.0+1.armv6l-linux-gnueabihf-cxx11.tar.gz/sha512/1e4e6a1a91ff1093b6441b43e50dd2cffa14d8cacecb6d812fde94164961e44569c17d74c65feccd613dee14311478bda112088d245e89bb307a3453e4d4d378 -LLVM_assert.v12.0.0+1.armv6l-linux-musleabihf-cxx03.tar.gz/md5/0155f81732916dcad2aa40b14d9db752 -LLVM_assert.v12.0.0+1.armv6l-linux-musleabihf-cxx03.tar.gz/sha512/7521fb007a0d589c9e70f7434afdc9e12867b6f82e6b7bc4c1f59fa337149648d6ea0367ae9dc7bb88840f6db05734d921f8da86633776a48529a0d6838feeee -LLVM_assert.v12.0.0+1.armv6l-linux-musleabihf-cxx11.tar.gz/md5/90095ad6a9506c7e83b195becc9f9cf4 -LLVM_assert.v12.0.0+1.armv6l-linux-musleabihf-cxx11.tar.gz/sha512/15d34c652513a25d967d2721b4ab196f570fa80e02f17a905240ae838aafeb4fc88c99810c26558babf35ef2b478b067126d76f1e4c9366a143b139640a14939 -LLVM_assert.v12.0.0+1.armv7l-linux-gnueabihf-cxx03.tar.gz/md5/0384e43e079b05f8cc2bbc23012794be -LLVM_assert.v12.0.0+1.armv7l-linux-gnueabihf-cxx03.tar.gz/sha512/c599404cfc5b78342ce8f4790b6f9b1d7e7cc0e26e674040d1538d676e11c1c95734bfec7a7869a5eeef20641ac3c4b510bc40f2c6a1ef40dfd196d975c0d596 -LLVM_assert.v12.0.0+1.armv7l-linux-gnueabihf-cxx11.tar.gz/md5/7d1c3fd8fe1458ad5e8996dd282087e8 -LLVM_assert.v12.0.0+1.armv7l-linux-gnueabihf-cxx11.tar.gz/sha512/c5b378c395be0339639baf8f10918ca2c6eed59a8fa8a34601e26c2433c6b543e92f71b73ceda254fa41f5b73796062758df26fe46335882c70c31c97ec128b5 -LLVM_assert.v12.0.0+1.armv7l-linux-musleabihf-cxx03.tar.gz/md5/6b42ab461336ea90274db8d059b7eec6 -LLVM_assert.v12.0.0+1.armv7l-linux-musleabihf-cxx03.tar.gz/sha512/3cb43d785825705567cb2b557a19486c75810d223e8ae828bfa9502de38f4bf76a3913634402529bda9f4a7525cc04fc33ab2a152c5dabb5adbbfd2497ade3fd -LLVM_assert.v12.0.0+1.armv7l-linux-musleabihf-cxx11.tar.gz/md5/8fa56521559c7bc15c52e3282b75e377 -LLVM_assert.v12.0.0+1.armv7l-linux-musleabihf-cxx11.tar.gz/sha512/9632ff9a34cb92527eda6b3904f3444dfc79577a30d047062d1a1320fb0b91fa8bd2ff061ef075b2a7340db330800e9ca14f26090ede82707e92f6bb449be3ad -LLVM_assert.v12.0.0+1.i686-linux-gnu-cxx03.tar.gz/md5/b93efe32fa26b868a37b698d27aff94b -LLVM_assert.v12.0.0+1.i686-linux-gnu-cxx03.tar.gz/sha512/fc3d05bea5f40ae893585314f6f7fbf92eebd58676489760c8dc3e5a7bba1963fc251a87d685c3fa1922f9d5e63cb59645b2126b3746258bc01acaeeb425796a -LLVM_assert.v12.0.0+1.i686-linux-gnu-cxx11.tar.gz/md5/01cb79e3c4d4d198f53fe0f79223ad03 -LLVM_assert.v12.0.0+1.i686-linux-gnu-cxx11.tar.gz/sha512/8620f2339e270c3cb5f455cc95acaa11bd9539475e64786c1869cd8582442812e732b903cda89a06bca8abf2aad3ff111f320fdd54e52d96ece6d57b35da3678 -LLVM_assert.v12.0.0+1.i686-linux-musl-cxx03.tar.gz/md5/84948b34ac2d1a3d3e5011df423070a9 -LLVM_assert.v12.0.0+1.i686-linux-musl-cxx03.tar.gz/sha512/df02613ed334d9d1d59daeb99e346e824e2cb0a35f092be5521e520ef0255c90a1d80b3b65db05162be2ae9707b7655da048f958b3dbcb7b57302a4105a57ada -LLVM_assert.v12.0.0+1.i686-linux-musl-cxx11.tar.gz/md5/d2e047b04a3a7aa8006b310f105f6503 -LLVM_assert.v12.0.0+1.i686-linux-musl-cxx11.tar.gz/sha512/3f574b15d3341e2897986a1cab9a883582c1eff594b4d952550ac4753b2ee795f8f2c6947cfd8dc1ee2dd2a5ed4414a11675dd86f53088274aa6d5c71111dd32 -LLVM_assert.v12.0.0+1.i686-w64-mingw32-cxx03.tar.gz/md5/1bc857bdf2d143fdf808a956ca528f05 -LLVM_assert.v12.0.0+1.i686-w64-mingw32-cxx03.tar.gz/sha512/0c2357fa990b20f247487a22a2d73289b7288a23269d7212c4066dd86ba02a18eff59be86e77b6cd50cd20ef05cc50bba8ed7fb7cddcae7c61603ff556e01fd0 -LLVM_assert.v12.0.0+1.i686-w64-mingw32-cxx11.tar.gz/md5/baed06cea973e29804f05ed77c6974fa -LLVM_assert.v12.0.0+1.i686-w64-mingw32-cxx11.tar.gz/sha512/b119901a524211cab7fd5eff962722fe5768975775267134094990a682d68779dafc9a9fba0b011e6927fca65e2cd52bee3e80fc505eb9571f32ccf41dbc1bb4 -LLVM_assert.v12.0.0+1.powerpc64le-linux-gnu-cxx03.tar.gz/md5/be94db30f358856a1e246be7355be7cf -LLVM_assert.v12.0.0+1.powerpc64le-linux-gnu-cxx03.tar.gz/sha512/de63c33dec3440626315457a93a860230cce3c8cb0bd967459ffc12af9bd0684fdf3c81edf7440ce2dcd02367dd3e5679238c588ca52daa870308bb6b3e56fce -LLVM_assert.v12.0.0+1.powerpc64le-linux-gnu-cxx11.tar.gz/md5/df5844b2dd49fe0eb4eac58fb22b7f8d -LLVM_assert.v12.0.0+1.powerpc64le-linux-gnu-cxx11.tar.gz/sha512/ef4a99aa6957d11aaa8a94027f6a7c2b7800f9b8f3fd8f7a7e9762383ac0064245e695c7040d9189a47ad7f95b1a0760fa6b655aa0f44e95d7ba684b9ccf174e -LLVM_assert.v12.0.0+1.x86_64-apple-darwin.tar.gz/md5/bdb347aa9b67ce6d24aba48d34299f0b -LLVM_assert.v12.0.0+1.x86_64-apple-darwin.tar.gz/sha512/527164a4db3e146f72eee0f2972209cf9eb705c3d614f0e505e0b503ef2a0e7986eeacdbf3e1197631454c90bfdc6f55dfc80c85a1537c3791ea0360610ffe19 -LLVM_assert.v12.0.0+1.x86_64-linux-gnu-cxx03.tar.gz/md5/a900923c8800c1860d5c98f9172b4c75 -LLVM_assert.v12.0.0+1.x86_64-linux-gnu-cxx03.tar.gz/sha512/04732d78b628b8fb06b2368d1ed48d21a3aefd5def2566f7fa17ab279b99e9fb0c0cb7f1d65933cbc6ff473c4e566034066666838644f9792eaa1d4ed0a8122e -LLVM_assert.v12.0.0+1.x86_64-linux-gnu-cxx11.tar.gz/md5/7669055a5e43049fc14282d9a37bd39d -LLVM_assert.v12.0.0+1.x86_64-linux-gnu-cxx11.tar.gz/sha512/71a8daba8baae164a6af16353d49a3f5bcb4b41714813659d8d488d7c8d26ffd8fbec92c6b53b98f05a4234224df81eebe7006e0ec5567518d7b42fa285be1a3 -LLVM_assert.v12.0.0+1.x86_64-linux-musl-cxx03.tar.gz/md5/1c38ee7ccb6dcbe22698f2eb08ffa627 -LLVM_assert.v12.0.0+1.x86_64-linux-musl-cxx03.tar.gz/sha512/dcd059ac9121f59507391657baf4c8eaaea7f531adc0ca02ea688d09643ada9e10a74e6441755014914f3f1764b90f99299ed4a3af5b234ec64cb5ed84934cb0 -LLVM_assert.v12.0.0+1.x86_64-linux-musl-cxx11.tar.gz/md5/a98e8304dd300af4b14211fd5f5c8a68 -LLVM_assert.v12.0.0+1.x86_64-linux-musl-cxx11.tar.gz/sha512/2a4a567d681a42cb6b05059dd68646f85841ba431eecfa36d0b8d0d0a9290d3aa9a628317050711e6c3a599e48b77d1988cfa9e4429b07e9f371741aa8d6f841 -LLVM_assert.v12.0.0+1.x86_64-unknown-freebsd.tar.gz/md5/9c92e5737faf62609844983f1603f75f -LLVM_assert.v12.0.0+1.x86_64-unknown-freebsd.tar.gz/sha512/dfe1f1836d74693f4061a07d834f622c6c9142ce8c949c07a5ca9a0976feecc67a483edcb1ff4dfab04fd54f063c0890655e855f55734d81fa3d595fcfc23109 -LLVM_assert.v12.0.0+1.x86_64-w64-mingw32-cxx03.tar.gz/md5/578f4ab4fd290342f3290e5b182af9c4 -LLVM_assert.v12.0.0+1.x86_64-w64-mingw32-cxx03.tar.gz/sha512/f8d23c8b994f8e503d041322dbd68b0d5682d8939480afab620ee861799000ba91571f59832f148dcd97cb0ab2bac9691eaa83107b98b8dbdf99569bc1b77432 -LLVM_assert.v12.0.0+1.x86_64-w64-mingw32-cxx11.tar.gz/md5/818b94c89b0af9f9e1dbfc98db278d03 -LLVM_assert.v12.0.0+1.x86_64-w64-mingw32-cxx11.tar.gz/sha512/672853d70cd25b13249479c1c831ba121e164a1aefbf46d6b9647501bf746b0925538bf126c552317482b9729fc9653800246ff25206775f5f5c6fb4196bffe9 -LLVM_full_assert.v9.0.1-1.x86_64-linux-gnu-cxx11.tar.gz/md5/1faea42ae449b43c9f3119ccc0c1b375 -LLVM_full_assert.v9.0.1-1.x86_64-linux-gnu-cxx11.tar.gz/sha512/c99baba5a831405d4ad4d8636eefbc260fcffcb8026fa1537cf63dc79d71dea7e57b52acf6815cbbc0aec8ae8c9aadfb1349791b0b31cfa8418529faa494195e -LLVM_full.v10.0.1-0.i686-linux-gnu-cxx03.tar.gz/md5/68d90f435664d4fef450eff70539dca9 -LLVM_full.v10.0.1-0.i686-linux-gnu-cxx03.tar.gz/sha512/65b07bc5f6145b063d7bc8d35fd22a2d578cd972c74b08ec827b9980e4ceb1fd77ce5ba921cd0d907643594fe73d67a7b56c699d3e64f9ac6b2b6953972a4179 -LLVM_full.v10.0.1-0.i686-linux-gnu-cxx11.tar.gz/md5/2128286984b014f41e1449e884a8f7c4 -LLVM_full.v10.0.1-0.i686-linux-gnu-cxx11.tar.gz/sha512/d8e99a78e29a7eec99bf5924c8f095b82fd7b020c19f8f41401eec514e468c48e489fd047401d751c8273f264fafd13964d1dd160d2be1e19d50f48133a7da9b -LLVM_full.v10.0.1-0.x86_64-linux-gnu-cxx11.tar.gz/md5/7718b789700c0f6f5329efabf6b0bfd0 -LLVM_full.v10.0.1-0.x86_64-linux-gnu-cxx11.tar.gz/sha512/94d6a951e5f6d6b9a2399a80b9cae5a52d37145956e4752f0bf2fb9b8b9e43e16987ed3833126efacef32831a200925f040fc2eeaf7b1f83817ed17954a993c2 -LLVM.v12.0.0+1.aarch64-apple-darwin.tar.gz/md5/e438402bcff0a77f20510badbb1f3c0f -LLVM.v12.0.0+1.aarch64-apple-darwin.tar.gz/sha512/14cafe77b353fbede64c736052032db77ced2757bb53696925899b79037a3b5a72d75f1ad8972a191e216a25a83f26517b0291fd246e0aad7a1ca040bdc7011d -LLVM.v12.0.0+1.aarch64-linux-gnu-cxx03.tar.gz/md5/8ff58f44d6f27d3dfb2b3670533a472c -LLVM.v12.0.0+1.aarch64-linux-gnu-cxx03.tar.gz/sha512/b9738d4b4f00c08cc06b3f1d73bdcaec96e578e02de08f14e2e084eabba934c24f9c4e65758e102515e3c9a1527612c468d8b178f2e87ca667f2e7a62343b1f2 -LLVM.v12.0.0+1.aarch64-linux-gnu-cxx11.tar.gz/md5/f4994c8abfd4fe71004b499bd95140bc -LLVM.v12.0.0+1.aarch64-linux-gnu-cxx11.tar.gz/sha512/fa01e3d6f154b695e9230c13365098af60ca5f6077d63e3cbc6c410a89615eb7634413532db4f93661289c590f4576c18488cae20ec5dfabe1c273cd97c18f7e -LLVM.v12.0.0+1.aarch64-linux-musl-cxx03.tar.gz/md5/52066c3a492d69cc0da23f0861f1f6a9 -LLVM.v12.0.0+1.aarch64-linux-musl-cxx03.tar.gz/sha512/db60079a09654f00a452c70862d1453c2ca8bf9b5ef055b66e99edfcc35a52a94245e21b0cd6acd88f556dd99c492b6f057dd48e3047286af0ed612493e895c7 -LLVM.v12.0.0+1.aarch64-linux-musl-cxx11.tar.gz/md5/b02a6d93f190aff2de4f03a1cd121a30 -LLVM.v12.0.0+1.aarch64-linux-musl-cxx11.tar.gz/sha512/3c0c9a3753b8e709361f1faceb02b3d19cc8e0c7a183601be528283c8871c92a234c3805206c37e1ec04577a53f57282b4874e4175e2ffb83b4b1ead744b9c0b -LLVM.v12.0.0+1.armv6l-linux-gnueabihf-cxx03.tar.gz/md5/88858237d7941887f27af62b7e249a62 -LLVM.v12.0.0+1.armv6l-linux-gnueabihf-cxx03.tar.gz/sha512/342d4bd418547f3b6543182a5593e21fd4af84eaab0b91ae04723e485b48accb2a119c7c89d766fcee2fa13af9ec3454da310d452e1262aa0e97fab9aa498422 -LLVM.v12.0.0+1.armv6l-linux-gnueabihf-cxx11.tar.gz/md5/1cdef3420fc7fba9e74765c839742350 -LLVM.v12.0.0+1.armv6l-linux-gnueabihf-cxx11.tar.gz/sha512/d7af8ec5abdc1ff75efa3f4f0546efa7d2328893b11533cde68a515a0d117272efa5e8bb1e821996ad12214668644bdf7a9a3f5e7578b24a174b5b04bc0cf1db -LLVM.v12.0.0+1.armv6l-linux-musleabihf-cxx03.tar.gz/md5/3ee4b9db085916dc73aa4131ff6a73a5 -LLVM.v12.0.0+1.armv6l-linux-musleabihf-cxx03.tar.gz/sha512/b456e096bbe2964f678f09edcfd49e0e8b4922984cfb1fc47358868eb099b82655ba8d5209ac31452af511d7c773de2a2f56a24ad0b36841d9f557ddb2c09a88 -LLVM.v12.0.0+1.armv6l-linux-musleabihf-cxx11.tar.gz/md5/bcfe6505477413c52c3193dd8d0c22fc -LLVM.v12.0.0+1.armv6l-linux-musleabihf-cxx11.tar.gz/sha512/50a2af7655acaa0e13f15cfcf490b334e104cdc847ddd5900fae04b322ecdecc69d85bd3b15b6170f584fe364dedea140e1fbd9a8835499067da59f4b665f849 -LLVM.v12.0.0+1.armv7l-linux-gnueabihf-cxx03.tar.gz/md5/c11d635651c82dbd5f0038f24afdcb03 -LLVM.v12.0.0+1.armv7l-linux-gnueabihf-cxx03.tar.gz/sha512/da3676b598851f07a875fb3282f2a1c078d0f447213049dac6e33bb07b5334d332df6f26b1e0e851f85bba20a72e65e158f848c67563be9a6e23c9d06b1a7f19 -LLVM.v12.0.0+1.armv7l-linux-gnueabihf-cxx11.tar.gz/md5/a299db2b5337c8b79bb0f37a39929c13 -LLVM.v12.0.0+1.armv7l-linux-gnueabihf-cxx11.tar.gz/sha512/46c7f0737dd3f46cbd30173d39c268a4606b169d80b146070fd2c61f32eb31b1cc8ef509bd1bc7f0c197a4b7b4a6e3d45a320b4a11a27d6a0233bbc1d79dd90b -LLVM.v12.0.0+1.armv7l-linux-musleabihf-cxx03.tar.gz/md5/3f8c17f38d47008ef26457ca29cd626e -LLVM.v12.0.0+1.armv7l-linux-musleabihf-cxx03.tar.gz/sha512/265dad34a231c55b07f9fcc059dde0ef72c156374d7334372f0ee486f9c1ebe95e8ec187cc4b07623dc94b8f8def7d3235fba0ee11a1b8419d9b7a7182a91d5e -LLVM.v12.0.0+1.armv7l-linux-musleabihf-cxx11.tar.gz/md5/5e49fc12546f4b1deaefa249f7e1f77f -LLVM.v12.0.0+1.armv7l-linux-musleabihf-cxx11.tar.gz/sha512/85940dac65199307fe6a571b7f369b02430c4ac980c7fe35c1ca4dae6d29a1e5ceaa72151ecc4d8fd29116b82e1d1d4b9054fc0fdc1de31becbdef1365164ecc -LLVM.v12.0.0+1.i686-linux-gnu-cxx03.tar.gz/md5/74c5e7b4e2bb44879f8a907d54c57398 -LLVM.v12.0.0+1.i686-linux-gnu-cxx03.tar.gz/sha512/41124a32c83e19e0fbd0f0c870bdda7d9a8f59ae51ec1017eba203e01e7fbc33b43334e12154ab0be57892f5bf85faf0c76c375da77e7c9097caf54b45a0d19b -LLVM.v12.0.0+1.i686-linux-gnu-cxx11.tar.gz/md5/6ff76e552a78453ac1e149a85179d7e8 -LLVM.v12.0.0+1.i686-linux-gnu-cxx11.tar.gz/sha512/8623d31b9bcc59ef3565db310e323e8b165c9c35a0ce170f5f5e2d58ff218974d2ad35ce1781a9558556a33247bcba2bcb1e1171254838fdc3780e9408df7525 -LLVM.v12.0.0+1.i686-linux-musl-cxx03.tar.gz/md5/8e097ffb90dfb3786ae1d9074314632c -LLVM.v12.0.0+1.i686-linux-musl-cxx03.tar.gz/sha512/96291e3c1620a358594be1dfd99354dcae76b9c7536ffb93bac93bf6523f323dc44d55b1faec85a763f1579f9ce0f1ae220f2943100d2f286dcb4cbd043ec088 -LLVM.v12.0.0+1.i686-linux-musl-cxx11.tar.gz/md5/bc19a91fcca8d8aad83f5b38c8db2a0c -LLVM.v12.0.0+1.i686-linux-musl-cxx11.tar.gz/sha512/ce5914eaa76e9eb21a218755211d613c4261ae284773222e40b383c20c5e7c6ef00be2836750cb1e85d2b1f6e65869e016d49f365d554ce845486fdd352c1b7c -LLVM.v12.0.0+1.i686-w64-mingw32-cxx03.tar.gz/md5/67f319faa58c136910cc6497eb73b234 -LLVM.v12.0.0+1.i686-w64-mingw32-cxx03.tar.gz/sha512/e5697c29f54bae9d9e551084ca702aafb09ff11f6de60aa723d90cad9675d18846c1cf2fc093ec1eb54c5db7f2328aa05555bf453f798cc3e96f79f2afebb283 -LLVM.v12.0.0+1.i686-w64-mingw32-cxx11.tar.gz/md5/e5d38ab0e686a0cc9452c1f1c81c21a7 -LLVM.v12.0.0+1.i686-w64-mingw32-cxx11.tar.gz/sha512/9cdfd778255faed49a53fcbc691a3a1c234b0649b13ba8499a90a61ffe7ee864ace982fd33e6e736f4466fc11d5a2c0b735bd68f7e5ac4eca5892ee76a5f0bd6 -LLVM.v12.0.0+1.powerpc64le-linux-gnu-cxx03.tar.gz/md5/c300da4c0c1a26115756d5b34583b0c2 -LLVM.v12.0.0+1.powerpc64le-linux-gnu-cxx03.tar.gz/sha512/1ef72ad1007363f25a410733efd5ce8c69d47718bd3df8d3e00e8cf22fd8ec3dbc4a19d4211a72877f90767a9b5d46318d5c059642de21a32072dd8099225add -LLVM.v12.0.0+1.powerpc64le-linux-gnu-cxx11.tar.gz/md5/32863e5fc4dbc7003326474e3b057412 -LLVM.v12.0.0+1.powerpc64le-linux-gnu-cxx11.tar.gz/sha512/2f3b726d787a6bb7cf92e7e4e91a9f72eac0da7fbf61b5cb94a49de812ec07b05b2cdb37800fce556071b410328dd7db1ed375961684e141fc54bc632ff10df8 -LLVM.v12.0.0+1.x86_64-apple-darwin.tar.gz/md5/0bd322858942def11a7a331211782917 -LLVM.v12.0.0+1.x86_64-apple-darwin.tar.gz/sha512/a33160fdee69ca06bcc1fc6843d19f306dacbf88037108c9fe5a0c57e2e4176c9ec108bd286486029312617a86da4791e123e89407a2ae71cae6f1726f44e9b3 -LLVM.v12.0.0+1.x86_64-linux-gnu-cxx03.tar.gz/md5/3efdba4e35e0c76b3d60bf8ad03fc321 -LLVM.v12.0.0+1.x86_64-linux-gnu-cxx03.tar.gz/sha512/0018caf8c878b482a7621d950687018586b5c0aaaa08a68d26855b40bc9b2ba60600e83d6bfd729b69d25eee3f0e4126afab9f7f523b41d5532400f6289508f8 -LLVM.v12.0.0+1.x86_64-linux-gnu-cxx11.tar.gz/md5/4ed4c4245ead0905cece3c5ac4c48886 -LLVM.v12.0.0+1.x86_64-linux-gnu-cxx11.tar.gz/sha512/609fba22a5d438d039f77fbb8c726766e71da9c768df83033d9b7cc8f178d2b25175427a5adfa6a004d61b610e4303f2a301e4ff5af51cf90296b883bd33c824 -LLVM.v12.0.0+1.x86_64-linux-musl-cxx03.tar.gz/md5/d78fe12460c99fc47f9139325c19d377 -LLVM.v12.0.0+1.x86_64-linux-musl-cxx03.tar.gz/sha512/698fd57da10afef2c5c43915292a4e9778bb9a005694391273cd2c2184aa792f914bf3f9e37bc31bb541054ddbe75122d01d34a4ac688a8b87ea22c795369fd6 -LLVM.v12.0.0+1.x86_64-linux-musl-cxx11.tar.gz/md5/49855ae6aaa48f3b6d55cf6a8c354449 -LLVM.v12.0.0+1.x86_64-linux-musl-cxx11.tar.gz/sha512/06bec6da4dba5956b35571dec54f81ccbd55a0e88aafa4d2d4477f50ca8f4c875853ce25db5fee236a2cd8be9f4b98528d051690db61efafb51c964e1953f159 -LLVM.v12.0.0+1.x86_64-unknown-freebsd.tar.gz/md5/f2362ea7f927839c1a12724e11c721da -LLVM.v12.0.0+1.x86_64-unknown-freebsd.tar.gz/sha512/e42248a84d8bc52d3cb23cb8c5b5d51560480333ff367d95ba5390e956bc78b8a48d5d7f70809aaa9288997db4b99a13e0e99f484f97713da9b167666c2fa284 -LLVM.v12.0.0+1.x86_64-w64-mingw32-cxx03.tar.gz/md5/4115b1aed76cfab64e6327593be41e2e -LLVM.v12.0.0+1.x86_64-w64-mingw32-cxx03.tar.gz/sha512/0c184e7e788dd5b9e76a10a6a0ca367eb0df76608d1d773abeec4583fcc8c59014eaf09ff9af67815c935a29816e055f9c4cf8d9c1ab5c98840bb24515f6ec22 -LLVM.v12.0.0+1.x86_64-w64-mingw32-cxx11.tar.gz/md5/2e663337eecbd7745e9decd60030f12d -LLVM.v12.0.0+1.x86_64-w64-mingw32-cxx11.tar.gz/sha512/198c8340de6ea5f01347d1465e0059ac6f83e23ab603c5789ed12a5a85eb738544cd490cf42a7799b44203fa19d55034c65b5a3f8e85eb2eade188d2bd32d43b +libLLVM_assert.v12.0.1+0.aarch64-apple-darwin.tar.gz/md5/c747bfdb199d77ba8c9a6984e114b007 +libLLVM_assert.v12.0.1+0.aarch64-apple-darwin.tar.gz/sha512/6ec360ce5d635e2e5841cdafb8290734d9ae28ff61ebc69e1bb621231e69c431ae93fd6798e70f02cc3476ba1a53a5317f75c57499b0e1e0feb4277a0e369a2f +libLLVM_assert.v12.0.1+0.aarch64-linux-gnu-cxx03.tar.gz/md5/8b8345f6f0139dd07751cccdf636f1d6 +libLLVM_assert.v12.0.1+0.aarch64-linux-gnu-cxx03.tar.gz/sha512/b34ed1f91df7593b456e0e3fc2fa059c8d76f8e0bcff253d2675c02424be34905e44d7b824ae0d2c032510a9205db719c0c839dec5f121193376b251f338f505 +libLLVM_assert.v12.0.1+0.aarch64-linux-gnu-cxx11.tar.gz/md5/f077d9bdd7c0a66053a3949141469007 +libLLVM_assert.v12.0.1+0.aarch64-linux-gnu-cxx11.tar.gz/sha512/91a68b1cc99339c438f73a1fdd85d3fc23b2ba5ceeeb3c5e6876ede22f53091c7f8da308a1cdc6d2a9d832ea2f4c2ece7536ce293570a1f639c043031926dc94 +libLLVM_assert.v12.0.1+0.aarch64-linux-musl-cxx03.tar.gz/md5/9b9b3101d9213a5a74e3a2704257961b +libLLVM_assert.v12.0.1+0.aarch64-linux-musl-cxx03.tar.gz/sha512/36d78c7881e55113b7717b120a9a691b3fdcf41e7d69ec3c8a04995268f13bbf2c6cc4faef34e7e38535eb75bd5d12f004e85f38fab13d7deb08171a54104fad +libLLVM_assert.v12.0.1+0.aarch64-linux-musl-cxx11.tar.gz/md5/9a2084773d4bc35d914aeb388dcedcf3 +libLLVM_assert.v12.0.1+0.aarch64-linux-musl-cxx11.tar.gz/sha512/08db23f8bc571d87e99fa7373ea582ca85827ac2b89caeb53cb91f6917d6c32b490e1c7604d8e31e9dd0448aa488b654e7e101cc5550632d762ce910616b1dd3 +libLLVM_assert.v12.0.1+0.armv6l-linux-gnueabihf-cxx03.tar.gz/md5/82c27f978b5f600df05eb43e31b17e94 +libLLVM_assert.v12.0.1+0.armv6l-linux-gnueabihf-cxx03.tar.gz/sha512/689b0d3b5697268ed17b5824af67d9a55889e9ec578fce989275a6dc808cc806ab8e4a71bd4f2bd4b6bd5bf65973929ff14d8b1f7830c31052b59c80c72cd77c +libLLVM_assert.v12.0.1+0.armv6l-linux-gnueabihf-cxx11.tar.gz/md5/af0939467863fae96656e27968a83a4b +libLLVM_assert.v12.0.1+0.armv6l-linux-gnueabihf-cxx11.tar.gz/sha512/4dce41fb4f24d2af99b6cfa30b40cfc00d6f547089551de6af7a44878559e6b412060a93358ce1ef41a1d3da7b522d0aa94f0c9f24c78e9a68c6e8e27ca7ef16 +libLLVM_assert.v12.0.1+0.armv6l-linux-musleabihf-cxx03.tar.gz/md5/684c09fb69a415c292b4965669a21542 +libLLVM_assert.v12.0.1+0.armv6l-linux-musleabihf-cxx03.tar.gz/sha512/3a275e3a112e120c8e10b1563a4874664db95ca2d555229f48b6c31a7eb9407e74f890c3c37ba8f58ed37b38a91e3a775abee4a29508ef1531ba31a902f18458 +libLLVM_assert.v12.0.1+0.armv6l-linux-musleabihf-cxx11.tar.gz/md5/e62d3df087506b8c3457fa77fbd018da +libLLVM_assert.v12.0.1+0.armv6l-linux-musleabihf-cxx11.tar.gz/sha512/67bdfaabc3107ff6b8a4813caa8dec38e94f4e6b297c353fea219e3695c20399466795fe5efc8bd46636ad68f1f25ac967135eb49b8ec4766720eeb282a574ab +libLLVM_assert.v12.0.1+0.armv7l-linux-gnueabihf-cxx03.tar.gz/md5/4f4010c5d82ca20e7064937a449e617a +libLLVM_assert.v12.0.1+0.armv7l-linux-gnueabihf-cxx03.tar.gz/sha512/31cd440634cb00493be58a4eb711f9e89a362b870d5167d8baa6273d700a0001e414cf3427285cd6d8d31863c6a136f63efa27b1166d7b382fb7a33b2cc4f84e +libLLVM_assert.v12.0.1+0.armv7l-linux-gnueabihf-cxx11.tar.gz/md5/9d7f3017c1e21220c92c46449d41ba3c +libLLVM_assert.v12.0.1+0.armv7l-linux-gnueabihf-cxx11.tar.gz/sha512/9e1b9b80bfc313d08cae8d62ebb055fa752f5fcb9ba42606e0e53028f6d5df372d535cf70da2c0d1cc86f6ce15981b1b5f9f721c24197232609638dcfbc73d48 +libLLVM_assert.v12.0.1+0.armv7l-linux-musleabihf-cxx03.tar.gz/md5/9f74405d26debd6ed6743f6f8ca8bd5e +libLLVM_assert.v12.0.1+0.armv7l-linux-musleabihf-cxx03.tar.gz/sha512/12c2c415bdf7669f10f60f3ab61a506b864cc440886d55d4bfc6d588f0187e0a04de09f3da2b3fd00652ab3688a74771c06603e895c9f7de60bdf317e43e8837 +libLLVM_assert.v12.0.1+0.armv7l-linux-musleabihf-cxx11.tar.gz/md5/0543b752e04125e97a087748785b9987 +libLLVM_assert.v12.0.1+0.armv7l-linux-musleabihf-cxx11.tar.gz/sha512/11e76a67c1f6deea206c644463a3a4660ccea97b79300e3430f10f86a7115f933bed78590033358c8a2ad04375ab7546b42a8730a9bb40e0a9b4352ffedbc481 +libLLVM_assert.v12.0.1+0.i686-linux-gnu-cxx03.tar.gz/md5/e43db260c7b4f918da8b8e234437407a +libLLVM_assert.v12.0.1+0.i686-linux-gnu-cxx03.tar.gz/sha512/367b42e601d7684805ff627b32329aed091d02fd791ebd5d661a81baac79326f4c9b77de410f7bbf1ea2a7904e6f090efe81a145ca137dd4b01dfe2d5cd7ecf5 +libLLVM_assert.v12.0.1+0.i686-linux-gnu-cxx11.tar.gz/md5/8dec2cb7eadd13aede78f9d5ce60296c +libLLVM_assert.v12.0.1+0.i686-linux-gnu-cxx11.tar.gz/sha512/0d36b28f5bfd35c2e0560da334430272ca0c70695f2d70f7e93edaa9308fe69f9a895615158805ab305603795deab0bb30a17f3f1690340cac064f35d2b1e6ab +libLLVM_assert.v12.0.1+0.i686-linux-musl-cxx03.tar.gz/md5/27c4856ac7778ed1c45c34695003a0ea +libLLVM_assert.v12.0.1+0.i686-linux-musl-cxx03.tar.gz/sha512/1507d6f57c794c48678e8826b885917046db12457b7b9b188b334fe64303199f4170e7c536165c5660911e2ee41f8251cacf0a8ce0bc44fa74bd9ddd0b0f1265 +libLLVM_assert.v12.0.1+0.i686-linux-musl-cxx11.tar.gz/md5/ec26cc534387af2bda1d26988c805b93 +libLLVM_assert.v12.0.1+0.i686-linux-musl-cxx11.tar.gz/sha512/b3b546fc5b3548d1513aca5dc442a3bd0c2a7d7b18507ce614c70de759f986a6ff999ad9dd8701752d8c9671d2d0343ee37c2de4de6b69672983827dc9d0c46c +libLLVM_assert.v12.0.1+0.i686-w64-mingw32-cxx03.tar.gz/md5/fb41f85924397c3511cf32375ad2ea6c +libLLVM_assert.v12.0.1+0.i686-w64-mingw32-cxx03.tar.gz/sha512/b97e2e98e9e39cfc90a4b6a4e6c82027034f7fa24dc286e4df5add37308b64156c5a631543b9c674973d3205bc4ec3b9813ab66982cf3328195db19472f9f071 +libLLVM_assert.v12.0.1+0.i686-w64-mingw32-cxx11.tar.gz/md5/57b18de8e7d8dac8fdfb1bb65956eac6 +libLLVM_assert.v12.0.1+0.i686-w64-mingw32-cxx11.tar.gz/sha512/21cb62852389bb9ab4bff38b1c073c6f46ae324757dea8f267a3826fc4db3918873d70a236431a8bd921db3f8d327d6f08ebfcd69a70123f761ab5af15ffb8c2 +libLLVM_assert.v12.0.1+0.powerpc64le-linux-gnu-cxx03.tar.gz/md5/3ef3f53a78f5927dbd73331f43575129 +libLLVM_assert.v12.0.1+0.powerpc64le-linux-gnu-cxx03.tar.gz/sha512/92b9843e537ac5c15ef18c6e1e3b7b1e95f7638ad14ab9ecb20aacef2cb1062d87ac8de993abf404bcf06b5523e9f7060f6d419df282ff4e1833517832d93c33 +libLLVM_assert.v12.0.1+0.powerpc64le-linux-gnu-cxx11.tar.gz/md5/e065f6bfa090d9d66b23ffd6f8e5285e +libLLVM_assert.v12.0.1+0.powerpc64le-linux-gnu-cxx11.tar.gz/sha512/778a990a0c4193d04077fda3e3bbf1420d96e689882a8bcfd24202c8f656eeec814f68cbe5de6fad4259ef0837ad773156885a5606d107b3371be278f4dd716a +libLLVM_assert.v12.0.1+0.x86_64-apple-darwin.tar.gz/md5/128dd6801aff034cbdf90c3a9d446954 +libLLVM_assert.v12.0.1+0.x86_64-apple-darwin.tar.gz/sha512/d8d4fbba77498abd154647edf5eea6d6ceecc6a836b1ce6b75e6d42949255e1e785ea9fea590e4f65df522aeb896843a52d39ad6f5f6cd80ac58f27bc9048786 +libLLVM_assert.v12.0.1+0.x86_64-linux-gnu-cxx03.tar.gz/md5/f6cc8374c37872d6846c54b7bde44592 +libLLVM_assert.v12.0.1+0.x86_64-linux-gnu-cxx03.tar.gz/sha512/31e28ffa3d9a8c8a86d08b9a3e50d9e021c010fa9ec0222c284fc7af86aa6a71ee252d109cae8e02dbcbad09126e01ab2311d55e9dee9939a162a472f3f5e517 +libLLVM_assert.v12.0.1+0.x86_64-linux-gnu-cxx11.tar.gz/md5/91df95adb9d0df769c7c530e7b558171 +libLLVM_assert.v12.0.1+0.x86_64-linux-gnu-cxx11.tar.gz/sha512/89fc4aad84ba13e4024e331f9da29a28b1651a69c4ef47c52fb2a20c6c0cbbb319e9ee82b9604d5a934147adb7b29a07d360bdb6f69a8e95255303ce0c7cc2e4 +libLLVM_assert.v12.0.1+0.x86_64-linux-musl-cxx03.tar.gz/md5/d7933d46280095ed61c0346a14c19f95 +libLLVM_assert.v12.0.1+0.x86_64-linux-musl-cxx03.tar.gz/sha512/fb7fd1a0d254de08b7045421fa1aaf0f0594ccf50fecffe5c1c7c162553712cf401e66f76f34286669bbac034a6411bea9e9abb99b1a6f711c4d4f129c937ce9 +libLLVM_assert.v12.0.1+0.x86_64-linux-musl-cxx11.tar.gz/md5/298e051ca068f5b61a1851274451bc19 +libLLVM_assert.v12.0.1+0.x86_64-linux-musl-cxx11.tar.gz/sha512/76517d5456d9cd5fcb75528fc2968f8a317e8660b73c9e5665c22dbf84efda107b16942c809167e0d7eb8457b21f3c20ce9de62f5d0e433ea7d21b8d3b54a811 +libLLVM_assert.v12.0.1+0.x86_64-unknown-freebsd.tar.gz/md5/cadc91e0a65bf719abfbae53ea8e0158 +libLLVM_assert.v12.0.1+0.x86_64-unknown-freebsd.tar.gz/sha512/2097cfcf21ce2f37cb079934a9e7c8ef30739d20e1b8c2068e59b7e2d4254fa9cd051492b23e426c1f0c2831ad60612fa13f64fd30468826c9ffca25fcb5db82 +libLLVM_assert.v12.0.1+0.x86_64-w64-mingw32-cxx03.tar.gz/md5/fa0ce67539470c5a81912efc743f66c5 +libLLVM_assert.v12.0.1+0.x86_64-w64-mingw32-cxx03.tar.gz/sha512/ef89f6230942c90d59e6169e538668cb39c22c64ca0c880224ac0bd856ffb9c0d8b573797351ccb28eee240371fc03617b192116a92926def586f4deae54fb6e +libLLVM_assert.v12.0.1+0.x86_64-w64-mingw32-cxx11.tar.gz/md5/a54594fb8bd760fa03d58f52532cf3cd +libLLVM_assert.v12.0.1+0.x86_64-w64-mingw32-cxx11.tar.gz/sha512/4c750c00398ec35052b54610d0fa5459b28023db15c61149bd897bfc1af1330769c3845dcb54601bc5ba49644b8a9196893dc6b78b10aea9d36f2a3c4c759e9b +libLLVM.v12.0.1+0.aarch64-apple-darwin.tar.gz/md5/b2936e7dec075bb0074f5f315bfe86e2 +libLLVM.v12.0.1+0.aarch64-apple-darwin.tar.gz/sha512/c5c93d3e2cdcf28babbcbac2c4bbc681c03036f43b05e5699e6251e2d3a036543557e3828be40bbbd01f76d361e884b656099099712f7af742aa822e923d4cdb +libLLVM.v12.0.1+0.aarch64-linux-gnu-cxx03.tar.gz/md5/b0f763bf80430e5064ce1a4910b52c95 +libLLVM.v12.0.1+0.aarch64-linux-gnu-cxx03.tar.gz/sha512/e024bce71447ac86a752d1e041ce86d68a25a131fd85fee607ce9e91eb2b185c2db6982bd89f04aa7ec4f238e49586f8413fbe1f10cfc94bbe32f05a5900be4d +libLLVM.v12.0.1+0.aarch64-linux-gnu-cxx11.tar.gz/md5/648dfa6270a300d0d739218e76cb6e77 +libLLVM.v12.0.1+0.aarch64-linux-gnu-cxx11.tar.gz/sha512/50efed61e87dcacbb6b75b3a6413e522d5677c53f58def59fcc54b5d02d5e319b9bcb5d7e316611564f4845872902d870c4143b9f23e305629ba0e3b69dc81c7 +libLLVM.v12.0.1+0.aarch64-linux-musl-cxx03.tar.gz/md5/688b38b56b4d852735147b2a7dd6c772 +libLLVM.v12.0.1+0.aarch64-linux-musl-cxx03.tar.gz/sha512/764042743772bcb10f873a0f6478b3b8cde5f150d64e72db9da27623359ee94876ac68fca15f64bdf79378a8c88b7c590d2548ebd55723e2517128a679a1b046 +libLLVM.v12.0.1+0.aarch64-linux-musl-cxx11.tar.gz/md5/ec00618e64ad972293c4d71978a92cf7 +libLLVM.v12.0.1+0.aarch64-linux-musl-cxx11.tar.gz/sha512/670d2304f3db72d8b27c3acc682f3ff9e8f12f3797f80dead4cf6fad94a40f3307c2e534b1caf8392728b4768e3b216f322325eff86141502fa3359828c2b891 +libLLVM.v12.0.1+0.armv6l-linux-gnueabihf-cxx03.tar.gz/md5/13abd32c8f473d13b8f90512b9d969ff +libLLVM.v12.0.1+0.armv6l-linux-gnueabihf-cxx03.tar.gz/sha512/28d3c5d161a63c07e069becf43c303f38794f54db8ff3723f0c30c4d240f3db8d6d08e013d64bc38f8deb8353b87e32e646e9ceed74a42ce066e8df7c9a4c328 +libLLVM.v12.0.1+0.armv6l-linux-gnueabihf-cxx11.tar.gz/md5/ce3325b92fa32363bca54159693993d2 +libLLVM.v12.0.1+0.armv6l-linux-gnueabihf-cxx11.tar.gz/sha512/cc75076f095dfb59a51a3abd0ec5475b8b8495695c005a93c9fe721f5571b8d1801c0807691efad97c80e074f20c365e14ade7221cadae8de8779a1313d8aa49 +libLLVM.v12.0.1+0.armv6l-linux-musleabihf-cxx03.tar.gz/md5/7aaa8b88d7c2e0571731c5ab1f342a8b +libLLVM.v12.0.1+0.armv6l-linux-musleabihf-cxx03.tar.gz/sha512/56c8c300d3e6407d638b3c77871c763133e5081cf78b9803269780290a34784bd9ca7b9ab4219e4b15d90f768d15dd3bbfb6a7fc4747dcb04a3a239f8874000a +libLLVM.v12.0.1+0.armv6l-linux-musleabihf-cxx11.tar.gz/md5/c345cbb3e3cca42fc5363f6fa90a3ac5 +libLLVM.v12.0.1+0.armv6l-linux-musleabihf-cxx11.tar.gz/sha512/af037ac16498e5b09a21a31881c2f20792e0c191a1af852fa1159843484ee829eb7bdac25c27226cc726622504febe1ee06cf0c70a99ba7542d78b1f83a1415a +libLLVM.v12.0.1+0.armv7l-linux-gnueabihf-cxx03.tar.gz/md5/03fddb9a5f0e4e6e9ad146918b5f9594 +libLLVM.v12.0.1+0.armv7l-linux-gnueabihf-cxx03.tar.gz/sha512/2698dde5f63a0ca2408430d23084c1fdba2b9cf86e106dba3b9711672e237e49f294b5ce4e4459ebdd7da0e748b067ade6cdeb7d004ff4c121c5d71e50af9abb +libLLVM.v12.0.1+0.armv7l-linux-gnueabihf-cxx11.tar.gz/md5/d679753db557bddca088ca14537f4fa8 +libLLVM.v12.0.1+0.armv7l-linux-gnueabihf-cxx11.tar.gz/sha512/468943d42df129b61c758c5567d0838580611b06906fd36ed652cf0d7d58b6e23907a0591eb1e02425a54a55897e3845952b7d87c4dafd405b673c70a6240635 +libLLVM.v12.0.1+0.armv7l-linux-musleabihf-cxx03.tar.gz/md5/390e47b0ec2a37c3ec9a10f03fb0f369 +libLLVM.v12.0.1+0.armv7l-linux-musleabihf-cxx03.tar.gz/sha512/7f2fcaa1afd00f52d20128ba55d1f919a8c8284b7f3de33c56d6c772a9cbbbeea8c433bbecedc20ce4ddf5631423fe44ad5f12c616df46f689519377416a799b +libLLVM.v12.0.1+0.armv7l-linux-musleabihf-cxx11.tar.gz/md5/161d18aab34df5b02fce7ed5eeedfce2 +libLLVM.v12.0.1+0.armv7l-linux-musleabihf-cxx11.tar.gz/sha512/f403c9df31233b39d80c415cd69cdbbd0b38d2412d090edc41ef197de3c2c07bec1b19f7c1118c8c20fcdf372fe6cf26cca6065472783b534669d1ea8e3ac5bb +libLLVM.v12.0.1+0.i686-linux-gnu-cxx03.tar.gz/md5/b6763e4a6ba177701dd84e019e0cc4c3 +libLLVM.v12.0.1+0.i686-linux-gnu-cxx03.tar.gz/sha512/15df17ab921aed3a84eb8fb5121df6fd6b091548eac978cd7101f8f0e342da6ef3ffad47d1cdca3a264e63bc19fc879a220ac23b8cef8ce666be66f2c78d69f7 +libLLVM.v12.0.1+0.i686-linux-gnu-cxx11.tar.gz/md5/0c074540ba38c2f86c5bb5365455a8e0 +libLLVM.v12.0.1+0.i686-linux-gnu-cxx11.tar.gz/sha512/1fbb275226e859617deb45f239f5307d0ab1aae1fd69575793b900832ce5d15413e6e6d8ce659ec2376a71a3fd295c308c5e6d8f626f30a7d0642251fd78f8b3 +libLLVM.v12.0.1+0.i686-linux-musl-cxx03.tar.gz/md5/585ffb5cc1d49bccd3141092620d9903 +libLLVM.v12.0.1+0.i686-linux-musl-cxx03.tar.gz/sha512/ced158b091a88bcedd23df1a9e08dde44ae1bac83d3416319311279fe25fa13ce92fb408ea7a2451f10d2a0fbbc2f4dad7afbc7cf790b2b78c1fba9bec53c46f +libLLVM.v12.0.1+0.i686-linux-musl-cxx11.tar.gz/md5/52783b24f1bca4cfc8446c1b6cf9390b +libLLVM.v12.0.1+0.i686-linux-musl-cxx11.tar.gz/sha512/298ef4104e7958491687b6085b38ea67fa6ce319b35afa24c45a18f46709f96e9edcf5e897d6fe0d1b3bf8c64dd5cd92f49973378e151db263edaaca8fe9caf6 +libLLVM.v12.0.1+0.i686-w64-mingw32-cxx03.tar.gz/md5/02a50422d2b3fdaad78a6bcb809c792c +libLLVM.v12.0.1+0.i686-w64-mingw32-cxx03.tar.gz/sha512/06d6ec3ecf8560210a0fd59e7d4f63e778de8c810d24b675c2655472f4272b9e85de18d848d79f31122bd1b62cd4a00666d62d3d012cf789804f29f90c555aa3 +libLLVM.v12.0.1+0.i686-w64-mingw32-cxx11.tar.gz/md5/1b678f74c6336a2870529bf6ec8ddd17 +libLLVM.v12.0.1+0.i686-w64-mingw32-cxx11.tar.gz/sha512/86d6a0563497ea9121fe5bc92db738a03ca97c150f8343bdeba10e887f9c015b2b725fb9626c78babff9c633ae393b8323ff098b32d7225db67fb9053e6abbe7 +libLLVM.v12.0.1+0.powerpc64le-linux-gnu-cxx03.tar.gz/md5/72cbb46c59ce588587caf76e894a4f5a +libLLVM.v12.0.1+0.powerpc64le-linux-gnu-cxx03.tar.gz/sha512/d6648d53c0dfd705d7ad46ae716e1db4a1d767317b79fe07b89a1a9d83e1d3e3f4416417f5538e8b86fbcec1d00002e4b069b0d16f6145ae5426ecb5a418a40e +libLLVM.v12.0.1+0.powerpc64le-linux-gnu-cxx11.tar.gz/md5/336c8d1eea9f7e9a3c8d82db6a4ee0bc +libLLVM.v12.0.1+0.powerpc64le-linux-gnu-cxx11.tar.gz/sha512/fc2f286a5bd72b70c4416c3bbe0998be9a22b9ff6303a4dfabeda9e4acb393ae18c387d6a4fe05d41e352954f9dd5ef712614fdc51057e3ec37bf1a35b46e8e9 +libLLVM.v12.0.1+0.x86_64-apple-darwin.tar.gz/md5/7168391b6c79ab1ed805357dee26cc8f +libLLVM.v12.0.1+0.x86_64-apple-darwin.tar.gz/sha512/6fbe058c5e18d52b1ecabdf1bb89d616b1e5fce030eb076f35fd759c484dce6ce89c6b450cf82698e31e672826c55f9018a36ae5abdc306f7535ceca2ad8af2c +libLLVM.v12.0.1+0.x86_64-linux-gnu-cxx03.tar.gz/md5/3c494d8f385a75960e18145cc64461e0 +libLLVM.v12.0.1+0.x86_64-linux-gnu-cxx03.tar.gz/sha512/1149364d65bb209e9d867fa65036e67a0300e70fe7fb2a351ad6f956c1f60bf3ef6437c96fd63985fd45b0e5412cefce3c94279b92f64826ddeabc8ef43bd071 +libLLVM.v12.0.1+0.x86_64-linux-gnu-cxx11.tar.gz/md5/9797b1942c5d4fc33f207123856c8aa0 +libLLVM.v12.0.1+0.x86_64-linux-gnu-cxx11.tar.gz/sha512/080945439141816585a2bb35d9222bd940a6213e377a57636d165aef0029645397655beca2555831d53e7f933b7dbff35ef607b6410318880ff23e0f5b8f3db0 +libLLVM.v12.0.1+0.x86_64-linux-musl-cxx03.tar.gz/md5/14b68e9ef3aa2b407f74546cc4973aa8 +libLLVM.v12.0.1+0.x86_64-linux-musl-cxx03.tar.gz/sha512/6e73da793d4d5162747b3bf04f3c74977e685c4b6b316f8b9e1de83c42ebd55a8dfc14e028f550b22231945eef8ba846dff9a7418b37b916ddb4b9a865dde778 +libLLVM.v12.0.1+0.x86_64-linux-musl-cxx11.tar.gz/md5/231fc8bf6f2b869a98a6be1c3c15cf84 +libLLVM.v12.0.1+0.x86_64-linux-musl-cxx11.tar.gz/sha512/acc5125a0720372b32f2f38e2b6f1bc1fdfce4ecd557a475ebb783e01bbc1f5efeeeb08a4953be66973e947fc6f203295755e4eb41c2f968ec71bf1bdecbd0ed +libLLVM.v12.0.1+0.x86_64-unknown-freebsd.tar.gz/md5/936c10d179134961da65e94759f9eced +libLLVM.v12.0.1+0.x86_64-unknown-freebsd.tar.gz/sha512/68d449bc9fdd1554835d6237db6643893c00176b4dcf570dbd31ec5662d6fcc916752a33e1713f20ead8499911153d25306cc9d1f0b3cee6113ec9b971c7e780 +libLLVM.v12.0.1+0.x86_64-w64-mingw32-cxx03.tar.gz/md5/4e6ce12e5f8850833f80fadc7d154928 +libLLVM.v12.0.1+0.x86_64-w64-mingw32-cxx03.tar.gz/sha512/4801ffdff0d807dc7df2d076793ff4c3751c73eff5d208476861f1e790afb39b31ba4e1eeb15da07528aaa7c0e77ecfc545c989c5d3cca7edeb31bb6b6ce561c +libLLVM.v12.0.1+0.x86_64-w64-mingw32-cxx11.tar.gz/md5/414a7becaa5623dc0d7b4b4c15f848ad +libLLVM.v12.0.1+0.x86_64-w64-mingw32-cxx11.tar.gz/sha512/8868f3890140cbdbfb2c11d34ada28c2ac09a49a45b306e4d99e868e1f20b6e91b3a39c4a743ace4bf32fbc87abd6226e9242d3192aabdf1e7f04a62f57dc4e2 +llvm-12.0.1.src.tar.xz/md5/72a257604efa1d32ef85a37cd9c66873 +llvm-12.0.1.src.tar.xz/sha512/ff674afb4c8eea699a4756f1bb463f15098a7fa354c733de83c024f8f0cf238cd5f19ae3ec446831c7109235e293e2bf31d8562567ede163c8ec53af7306ba0f +LLVM_assert.v12.0.1+0.aarch64-apple-darwin.tar.gz/md5/e36756cb0c80b0e113d445afb9b6a074 +LLVM_assert.v12.0.1+0.aarch64-apple-darwin.tar.gz/sha512/ba3daac19b9ad0b0bc70c0dba8093ecd97e667440a414409e0414960ab5870927a65755d116ebf106e529c396cef3cc074882b86debd978467ec533deceedba7 +LLVM_assert.v12.0.1+0.aarch64-linux-gnu-cxx03.tar.gz/md5/828f9b84f074321b991708afb7320c09 +LLVM_assert.v12.0.1+0.aarch64-linux-gnu-cxx03.tar.gz/sha512/34efda2d8e07b2eecc19dc445a8ecdfdef2d3a17dfcb8ec839c76d1e4cde5b74240cd1d5d2518e312ace497672569b87d6beb08834861ea0aa1d8d3f48b990be +LLVM_assert.v12.0.1+0.aarch64-linux-gnu-cxx11.tar.gz/md5/ba42d8486199e8b6789805891035ce9d +LLVM_assert.v12.0.1+0.aarch64-linux-gnu-cxx11.tar.gz/sha512/0e1e1e1a1e4ce7568b22beccbb693001e6c32bc82e45c862287b77f4756d0c97a8e74d6e77fa768dc2a4c4971e2ec31bfe08feeb0aff67f095bb3f93af2b3dde +LLVM_assert.v12.0.1+0.aarch64-linux-musl-cxx03.tar.gz/md5/95f562abd7fc60627d69ca9c870cd076 +LLVM_assert.v12.0.1+0.aarch64-linux-musl-cxx03.tar.gz/sha512/58556d400148c2e28caadfc74722ff7dab35d1244c700fdd7da8daba9217eef78fe7cbddd94585c799942460e9fef731207ad3fb89b933125006fa58c66fb43a +LLVM_assert.v12.0.1+0.aarch64-linux-musl-cxx11.tar.gz/md5/d7c76a40a2f25357bac82d27e220f00e +LLVM_assert.v12.0.1+0.aarch64-linux-musl-cxx11.tar.gz/sha512/4e6408703ef2e6c36c267d316efbdb1a514dbffe08ee69f598801bf2d002fa6d34a7efb4ec8f091bc9f0db5d47c443aee95b1e65138f3f5011c7c7a62ecae05e +LLVM_assert.v12.0.1+0.armv6l-linux-gnueabihf-cxx03.tar.gz/md5/2ed619623c717da7f6182c1a126d5e65 +LLVM_assert.v12.0.1+0.armv6l-linux-gnueabihf-cxx03.tar.gz/sha512/2045fe4551457e350e16f0af6efafd8ff67e9540532535c6951627a72b21786ae69c993ff18b048a613f7f85fede279db9b8734c8e77ddf79a87d08c17f2d029 +LLVM_assert.v12.0.1+0.armv6l-linux-gnueabihf-cxx11.tar.gz/md5/cf0396c08a19433d326d4637cf0373a2 +LLVM_assert.v12.0.1+0.armv6l-linux-gnueabihf-cxx11.tar.gz/sha512/c3d5a0c62dbd97084434bb549430fe7c8a27a6c49dea4e141ab84b369507019472aa7f2edafe56f85d828550c7c78398f95b82fbe6358fe96a7fc3fbbb5ed4f9 +LLVM_assert.v12.0.1+0.armv6l-linux-musleabihf-cxx03.tar.gz/md5/198d203c3c469fe625a7878961692108 +LLVM_assert.v12.0.1+0.armv6l-linux-musleabihf-cxx03.tar.gz/sha512/b2c8da74ce54187fafb0cba187576bddb492f03aac5e310340e203204682301feb6604e9f282f22beb90e5e141d7f269b147085f4a099dcd6c1eacd89801b139 +LLVM_assert.v12.0.1+0.armv6l-linux-musleabihf-cxx11.tar.gz/md5/17ddbda46f0e2c756fdecdbc80458662 +LLVM_assert.v12.0.1+0.armv6l-linux-musleabihf-cxx11.tar.gz/sha512/d12850485f037f080285aa78375b6c07fdbdccdb62c2abf68c6a7366a7bf29c0836776e81d3a73bdade71f78d1ed289f3c8c899052ea4e7dda4848e0ff159e0b +LLVM_assert.v12.0.1+0.armv7l-linux-gnueabihf-cxx03.tar.gz/md5/447fdf5003ddcb12595f657249ef04d6 +LLVM_assert.v12.0.1+0.armv7l-linux-gnueabihf-cxx03.tar.gz/sha512/3dff913e74bbc3882adf2bb2c1bf2d7fd936304cd5f81ee9ab8c80544bd851185ef45160a04e7aca2fc4a9b6656f5616b3d301b533d7a3b40132346fd2c71c27 +LLVM_assert.v12.0.1+0.armv7l-linux-gnueabihf-cxx11.tar.gz/md5/a07d85ad41d9acbd1820c3e22cc94a2c +LLVM_assert.v12.0.1+0.armv7l-linux-gnueabihf-cxx11.tar.gz/sha512/f2652066abe9f21f2c9d2e1d21d72a9f6dd576f9da67a5b675278ea3a129ebea2f2964b1badccc6992bbabdb4ee25bcebacfa885fb3485f8596ead48f610e230 +LLVM_assert.v12.0.1+0.armv7l-linux-musleabihf-cxx03.tar.gz/md5/b793f725bf7c1e1e9f534aada1e97b64 +LLVM_assert.v12.0.1+0.armv7l-linux-musleabihf-cxx03.tar.gz/sha512/d801cbad6c58227196372360f8920dbd25e553947b21f30e8e28ba28f39dffb546f492f4802eea1a8d45b08fb6f52cd49552f91668e967424c442e1b6461808e +LLVM_assert.v12.0.1+0.armv7l-linux-musleabihf-cxx11.tar.gz/md5/cbf17dec00764c1e7d28b636b50f5b6c +LLVM_assert.v12.0.1+0.armv7l-linux-musleabihf-cxx11.tar.gz/sha512/fe70916536e9587fc3162e356a1a6d567bef10627b4659d529cfecc89ee23d77c7a5fcd78aaa966de475ee77882b58c8d8654c5a0ebf7aa2ac88da9587716ed5 +LLVM_assert.v12.0.1+0.i686-linux-gnu-cxx03.tar.gz/md5/da27739a3fbe68c77ee71eb853560b68 +LLVM_assert.v12.0.1+0.i686-linux-gnu-cxx03.tar.gz/sha512/f5e73904693a63b1647fee476fc4b7445ccb57b053a035489adc3a679b32e34edada461bf00611b6a11f1f31e73785de7f6e62d759fdb2e4bdf4b8ee0b2be792 +LLVM_assert.v12.0.1+0.i686-linux-gnu-cxx11.tar.gz/md5/061cff6ba872358714a921219d49da3e +LLVM_assert.v12.0.1+0.i686-linux-gnu-cxx11.tar.gz/sha512/2abbfa2949a7700b6d80cca0ced9499638fdf1d531c722727bd07462e81f6ae3b77273c399e1ec439665e09a34fdbe657847f215a3cff629bea784a3190d11f6 +LLVM_assert.v12.0.1+0.i686-linux-musl-cxx03.tar.gz/md5/4f20e6d98ff6c345401b1e33297ea399 +LLVM_assert.v12.0.1+0.i686-linux-musl-cxx03.tar.gz/sha512/e06a309a2204d1e446385ea0580b376545aed503b9b80d5a3f6f9aff4a857acbeac1f3364173b3a38f9f3dadf1f8ea916a0e5876ebb07f557d56f37f63e8f326 +LLVM_assert.v12.0.1+0.i686-linux-musl-cxx11.tar.gz/md5/a440f471f69dd9b5eec203f0ebada4f7 +LLVM_assert.v12.0.1+0.i686-linux-musl-cxx11.tar.gz/sha512/2e74cbf119de31673c5f706b189e2095af963455488fc7bf80eb2bbe2908dc0c2fa4222e72a1360c2c94962c401b82a90562736f815b4ae77265e7bbaa7b430d +LLVM_assert.v12.0.1+0.i686-w64-mingw32-cxx03.tar.gz/md5/ce9a8962fa72f49ddb3e308c496cc922 +LLVM_assert.v12.0.1+0.i686-w64-mingw32-cxx03.tar.gz/sha512/af85ab008e537d74c6babb994e8e0bccd557ccb28ab96b02f9c3dea39d764e1f2a2b8f6db79bd20d346e1df262c22f2add337a3038d12d6ef8234a4ce8240ea3 +LLVM_assert.v12.0.1+0.i686-w64-mingw32-cxx11.tar.gz/md5/6dcb876e704dac48dab81f6d670d17a9 +LLVM_assert.v12.0.1+0.i686-w64-mingw32-cxx11.tar.gz/sha512/1f0cf33673598d76303b9b88c6e14ae53d048a74df680ae79b443d59b289cb820d090be04533aef43fa501b776dd890a9da13d52dc964f3da1c0c1bf2999191e +LLVM_assert.v12.0.1+0.powerpc64le-linux-gnu-cxx03.tar.gz/md5/69fb775889a1c37e17f4d39c7d91f7d1 +LLVM_assert.v12.0.1+0.powerpc64le-linux-gnu-cxx03.tar.gz/sha512/cc6746a1ba64464fba170c206a652e8726c1e68c5929cb215ef84c47c79ffb4e8bb224e8521779bf547ab2d984fc4f34e0eb66bf2ec619f7899c2ec103c2bb16 +LLVM_assert.v12.0.1+0.powerpc64le-linux-gnu-cxx11.tar.gz/md5/20f6f2bdc44846e27eb6e48949abee17 +LLVM_assert.v12.0.1+0.powerpc64le-linux-gnu-cxx11.tar.gz/sha512/27d5bfa52012881364f761b99bd2de0f74ba486301f9c753bed47ff151cd33b9484be532f65e1b038da470f7995454c12f75fb5e908f43caa8f0929f266bf14f +LLVM_assert.v12.0.1+0.x86_64-apple-darwin.tar.gz/md5/4998b04416cecd78260eea1840b919b4 +LLVM_assert.v12.0.1+0.x86_64-apple-darwin.tar.gz/sha512/ec28bd785eea3d2e118e7a58fe787cbf2a40a3e3a45d9ba3c6ef876492f76a00f686881129fdcd34a0547321277a5a75d7c787b957833eaf4a78a02c8ec4b1de +LLVM_assert.v12.0.1+0.x86_64-linux-gnu-cxx03.tar.gz/md5/3422a9ac5ca936ff35ff0a996acaa181 +LLVM_assert.v12.0.1+0.x86_64-linux-gnu-cxx03.tar.gz/sha512/0988ba7e639edeb83fce221bbefd44e039e9d31af9fc15f74e2b897f8e0bf9a4e6752ae3adf452025e0e2413c4f212abf7e0f76aa4633663ee6889dcea08aa86 +LLVM_assert.v12.0.1+0.x86_64-linux-gnu-cxx11.tar.gz/md5/99d4b687edf92129bb0e113a3efe6f83 +LLVM_assert.v12.0.1+0.x86_64-linux-gnu-cxx11.tar.gz/sha512/cd464b130428e891df2f2cb9fb3995e71e6249138ccd96fd4d1932b96186d145ae555b7d5b3c214ac9974c995a4d288202c17482467b7934fc30514bae594f02 +LLVM_assert.v12.0.1+0.x86_64-linux-musl-cxx03.tar.gz/md5/344d868a03ae76a442a4e06e59584f89 +LLVM_assert.v12.0.1+0.x86_64-linux-musl-cxx03.tar.gz/sha512/1f3dfa1a2999b3cb7a4c4f46a486168231a5dd56b2557f4ca3fd15d40f1b18b9cc32ff69b5ca657c4d5c1752068d351be078780fea8d4dc503a6b56e757798f0 +LLVM_assert.v12.0.1+0.x86_64-linux-musl-cxx11.tar.gz/md5/9024015d75a14278813ce9c65a237336 +LLVM_assert.v12.0.1+0.x86_64-linux-musl-cxx11.tar.gz/sha512/5be1e537de5a0b24203373f21cc7d5878049322218c97baca1ea2da13dadafd03efff1fc817f8e314b032254356d5802e56d744b7f910dab75f41d4c8bd65449 +LLVM_assert.v12.0.1+0.x86_64-unknown-freebsd.tar.gz/md5/5b60dc9dd86fe85ee61352e91197f9bd +LLVM_assert.v12.0.1+0.x86_64-unknown-freebsd.tar.gz/sha512/6601bc4b76856e98615bd9a41e853f2c94d3e56e91ace9ec7b900f62ba7902b0a4276e21de01186ff2198c445269a2c7622774912a24fed5f8e30615a3c200c1 +LLVM_assert.v12.0.1+0.x86_64-w64-mingw32-cxx03.tar.gz/md5/6f72147189a9fb2de7bc4fcc768a137a +LLVM_assert.v12.0.1+0.x86_64-w64-mingw32-cxx03.tar.gz/sha512/c3c12a22c1e7dd80a15a9d8e5bf32d1352df943ddab7eaa75c85b26ba34a7f0a1df796e97bbfb1b95a134114d1ff14938fbaa6b6f8ef61188b53cd191ad206b4 +LLVM_assert.v12.0.1+0.x86_64-w64-mingw32-cxx11.tar.gz/md5/5c10619e2da3de264fdf27691aac5c3c +LLVM_assert.v12.0.1+0.x86_64-w64-mingw32-cxx11.tar.gz/sha512/4da219139e6420926aa4f2bc51171884c60edb35ea22fc5673d43576ecc383cf060f13ddc8ee872ccee628099e7c01d8b4c3ca1205eb7a9b214ce2a2ad7542f5 +LLVM.v12.0.1+0.aarch64-apple-darwin.tar.gz/md5/d2fabb7dd75ccac17875fe838703c6c0 +LLVM.v12.0.1+0.aarch64-apple-darwin.tar.gz/sha512/933a281a212a72e815e94644d28e259c2529868fce5a07bb005109f8b964f4cdd2aa309c65dbf5a45786689e242064ca0bb1d3a01778f438f83e1a566003933f +LLVM.v12.0.1+0.aarch64-linux-gnu-cxx03.tar.gz/md5/acc3db12b256c4d19309bd8a043c7490 +LLVM.v12.0.1+0.aarch64-linux-gnu-cxx03.tar.gz/sha512/5f85f0f00c1c0db1b0cd816e7e1ce78d99ea91d886c67494489626c40417c72f49a6bdee2cb52b71b369172909481e92ab7d99bedf9a65589e02ac1001695838 +LLVM.v12.0.1+0.aarch64-linux-gnu-cxx11.tar.gz/md5/a0e3e199206f4ac941bf1c668123ddaa +LLVM.v12.0.1+0.aarch64-linux-gnu-cxx11.tar.gz/sha512/1a905dbf74f8ccce1ebf276b9a9f86478bf4e582be233bfebd6a12f78895ee014ce85b3a54fac382651abd461691643373f634efc41f923e76d02075d096c453 +LLVM.v12.0.1+0.aarch64-linux-musl-cxx03.tar.gz/md5/74d20c4eab17b1b78752ef1288fa72ee +LLVM.v12.0.1+0.aarch64-linux-musl-cxx03.tar.gz/sha512/19f1f83fae86468045ce0db8e9adcd76d7613b9bcb69bf2f63933020a0508cf6114bffb105c7280881b9504413ec88bb189c244a00ee4bb00a59e781f1ab10ae +LLVM.v12.0.1+0.aarch64-linux-musl-cxx11.tar.gz/md5/ec0d46c670124a577fec23373d1bf554 +LLVM.v12.0.1+0.aarch64-linux-musl-cxx11.tar.gz/sha512/6478e8060b5bd8f9dabf379a1f967f7e3c5b25382eedb45b5ba95f63b3c9c072c55bbe5ade9be55d27e5dcdd4cdda5cfbc24dff9e8a72ca0d338975c2769a0a2 +LLVM.v12.0.1+0.armv6l-linux-gnueabihf-cxx03.tar.gz/md5/eeac65dd85aa6d66ef6cad2150d0906a +LLVM.v12.0.1+0.armv6l-linux-gnueabihf-cxx03.tar.gz/sha512/e66102d5103980d25781945e54cf5c50b9029b57df052a94b2c4481dcbee0c30cee0ec78f5da523385482204f9d9875575a14af21dc8dbb0cf08127f9a3225e8 +LLVM.v12.0.1+0.armv6l-linux-gnueabihf-cxx11.tar.gz/md5/6ffc46886a2e730bbc7fcfdb76b627db +LLVM.v12.0.1+0.armv6l-linux-gnueabihf-cxx11.tar.gz/sha512/eca9686b54eeda7b539acb8437fb43e2676e72501bf677de103502bb41ab708f0abb759e8be11f1e845da34aa16aa3f365efbafd10c326a1f02978a954b607ae +LLVM.v12.0.1+0.armv6l-linux-musleabihf-cxx03.tar.gz/md5/4dc0d110eb0953835e7cb624d82e1688 +LLVM.v12.0.1+0.armv6l-linux-musleabihf-cxx03.tar.gz/sha512/d49a4513f3fcd69c7b8521964d25f0747933561b41cb7c40058581d2feeb9f3ee5811784a93fab4784e594612415729835ae086c7b6a3235c0e506759e1d5b90 +LLVM.v12.0.1+0.armv6l-linux-musleabihf-cxx11.tar.gz/md5/19c73dafac806d36cb63c225ec8a0d2b +LLVM.v12.0.1+0.armv6l-linux-musleabihf-cxx11.tar.gz/sha512/50b4c36d3ea6b6a8570ec85ca02b454b8912c025e0ff28a9232585a0bc54dc90e2ce5ff20db5b4bb01359100cb74aa65517336486fce9abe5c90d5b9440fd0bd +LLVM.v12.0.1+0.armv7l-linux-gnueabihf-cxx03.tar.gz/md5/4ff58627dc352dc8dbcdddfe15e11dd1 +LLVM.v12.0.1+0.armv7l-linux-gnueabihf-cxx03.tar.gz/sha512/f5d1c2c92c5999797a0892d2ed0ff64fd2b9ccaec3f091d17b5c76896bd99faf24b2ee95605772364087e79522bfab54b4ad2d4327e4bdbd410cd6ef2f3488cb +LLVM.v12.0.1+0.armv7l-linux-gnueabihf-cxx11.tar.gz/md5/4a9e0c6ad9bb5ddb511b246bd1794db7 +LLVM.v12.0.1+0.armv7l-linux-gnueabihf-cxx11.tar.gz/sha512/8ed5f76811231f5821fd192e7191187554ee770e6aa59794aef645d9a3fa3ac2b26ab1d0e849520c739171c41e7f00ce8872d868f5efad646f0feb16e2c0255f +LLVM.v12.0.1+0.armv7l-linux-musleabihf-cxx03.tar.gz/md5/7a03cf38fb4d11ceb2d67c282228f7d0 +LLVM.v12.0.1+0.armv7l-linux-musleabihf-cxx03.tar.gz/sha512/65b84023e2dc8e4da55eca0ffbd0921c18ce3c4e9cf8b95d56442c0cc6bdec25bb1063a273aed390ddbf7839a84588df92ef7152c2bd999984e62f81b03e53b7 +LLVM.v12.0.1+0.armv7l-linux-musleabihf-cxx11.tar.gz/md5/b8abd832fbe5b103c7fc53eb3a62d0c9 +LLVM.v12.0.1+0.armv7l-linux-musleabihf-cxx11.tar.gz/sha512/cf22eadec8131ec287bc72fdfc90e65f81ddd21ccb908c7c0a8aff79b72f17d5429f6a9e0748e9581e82d82d089f433b2bcdfe96d18b3cdbec3019150f91efc9 +LLVM.v12.0.1+0.i686-linux-gnu-cxx03.tar.gz/md5/cb62fed90d93fd1caae4bffa8568a923 +LLVM.v12.0.1+0.i686-linux-gnu-cxx03.tar.gz/sha512/e8459774501520179052ce27d6e28025776e81f90e64c6835671a82882f03c5835f6c0536c3d4742b8bf3456a787378a7883faf1592889d67c6b1861accb95fc +LLVM.v12.0.1+0.i686-linux-gnu-cxx11.tar.gz/md5/cdd8eac17b0979f25579b5df14c22dac +LLVM.v12.0.1+0.i686-linux-gnu-cxx11.tar.gz/sha512/51a92d27b676e755cc4ef5762a68ed323b9169bcc6891f1f979dcdceafa5d5a627abfd2a048726fc05bfe8063e678645e52499409143cb91fcc1640ae1a803db +LLVM.v12.0.1+0.i686-linux-musl-cxx03.tar.gz/md5/292dad78439e6adf32e4c52991e48ee4 +LLVM.v12.0.1+0.i686-linux-musl-cxx03.tar.gz/sha512/7c99a2a768c31a982d773a954109f2e1c6bd7c697e89e9b21a53fbdf91a46688a471cff2652fb7fd7809b0202526f8a94708958f1d1cbc49c000ad88c3c56a21 +LLVM.v12.0.1+0.i686-linux-musl-cxx11.tar.gz/md5/287b98d99f9cc1537206cef8e962babc +LLVM.v12.0.1+0.i686-linux-musl-cxx11.tar.gz/sha512/a7185740df4ab6e8de6d77c4cb810502fec5b5f4b1f24a5dd87f717ef8d881631fb25842236fb177a8fb193d349e9f0072f94632b080147af6dd451f3064dcce +LLVM.v12.0.1+0.i686-w64-mingw32-cxx03.tar.gz/md5/bde06b7de8bfe67bd17a3eddeceda181 +LLVM.v12.0.1+0.i686-w64-mingw32-cxx03.tar.gz/sha512/e08c227617f9baccaa3200d82bd98017a41fe4230d3eddce11e9224e63ed7206124931ffd2553d61d5a937213da74f605611f531dd14405de4d43873b9e32afe +LLVM.v12.0.1+0.i686-w64-mingw32-cxx11.tar.gz/md5/261802abe708e1ba66e31e5247c39c7f +LLVM.v12.0.1+0.i686-w64-mingw32-cxx11.tar.gz/sha512/779b8b78be912aed4e3ef52ffc9331ea94d223d86dbc470b4690c21869522937e9e52cbe325e7795bc92f1f5a4aaf26f5abfc2f24aa3a0314d5e19d8842d169b +LLVM.v12.0.1+0.powerpc64le-linux-gnu-cxx03.tar.gz/md5/b5ddd1f4eaead404012fafb404887817 +LLVM.v12.0.1+0.powerpc64le-linux-gnu-cxx03.tar.gz/sha512/4b607174be6f39cecc39f71db661a207ea034192f652782c1a49a5d8efd3eec5488eb8d70554a9b2ab8a3dad74f90b243d5ff8651fd6e366064c06ded6cfb586 +LLVM.v12.0.1+0.powerpc64le-linux-gnu-cxx11.tar.gz/md5/5623d2d0a1f3b1de282d520a4345d9ee +LLVM.v12.0.1+0.powerpc64le-linux-gnu-cxx11.tar.gz/sha512/ca7c2eda3a33682289b39dcff0d203927faa805b89ca2e452ecc98f3feac86ce0423ed8f53ca2ccde70f661e458e39023bb1bc702f1c3bfbed10e252a1914c1e +LLVM.v12.0.1+0.x86_64-apple-darwin.tar.gz/md5/eb59f57374df1072421a64f61b53eebe +LLVM.v12.0.1+0.x86_64-apple-darwin.tar.gz/sha512/4e05f3e0f4eb4f0240c44427b6e6207304e9828bb18be0741bcb794214c64f01b7464bd40f5ace49428f805b08b1b3ffd48b0f2b463f4df1f9441da0d0aa2986 +LLVM.v12.0.1+0.x86_64-linux-gnu-cxx03.tar.gz/md5/a1ea1dd2b8a37e8cf1f50ab1d5a8727d +LLVM.v12.0.1+0.x86_64-linux-gnu-cxx03.tar.gz/sha512/46423791f1fe0ae41868b6b2cecb4ed2cab818516e384fd74668b9ea60c0142b839ed559259e8af4aeef182d5179a001138f0f7ab8c0f2f71bfba1d087b5c8a0 +LLVM.v12.0.1+0.x86_64-linux-gnu-cxx11.tar.gz/md5/0284dff55154d6d35a9c143e4b4da8ae +LLVM.v12.0.1+0.x86_64-linux-gnu-cxx11.tar.gz/sha512/82bfc6ce434cdf0a8ef8df9a3af97bde370e14007bf42837446ab4561ea7d9336ff77853a2a5e6d8675f74d0739bff3729f3625e8a75bbc0aa469b11df156fcf +LLVM.v12.0.1+0.x86_64-linux-musl-cxx03.tar.gz/md5/9bbbb46e2b4cb35a038bc96e3f7c4621 +LLVM.v12.0.1+0.x86_64-linux-musl-cxx03.tar.gz/sha512/97a5ab75fdff62d85c5996286ffc30c757ca83d965ca7a9442b0a7be57d2daf4a0913442ed8db39b9712702ff21e4002df7df01e971c64e032767584f90febb7 +LLVM.v12.0.1+0.x86_64-linux-musl-cxx11.tar.gz/md5/3fbaf503543a175c681ff5a78e54683a +LLVM.v12.0.1+0.x86_64-linux-musl-cxx11.tar.gz/sha512/1a9b2774e8265f1d90b9eac051ff9841ae912bc9bef9b8871551b3a6dba0fb76ca87433ee2f5bac99c27d642afc54248cde5b32e3d4ed35e86d5ed104fc803ce +LLVM.v12.0.1+0.x86_64-unknown-freebsd.tar.gz/md5/e7661c57e4f198442b5f7142bdde26c7 +LLVM.v12.0.1+0.x86_64-unknown-freebsd.tar.gz/sha512/41380a4603d5b78035e8a3550826a69887ab0f0336384c7c6aa9d123c5aa68fbc780ff8142403a2e5b69d3bacc2a93f439bf3217335542a14380d13812bbe1d3 +LLVM.v12.0.1+0.x86_64-w64-mingw32-cxx03.tar.gz/md5/89400c38523fb8d13064beac9dc7dd20 +LLVM.v12.0.1+0.x86_64-w64-mingw32-cxx03.tar.gz/sha512/6de8dfaded2b61fa3780b08efce53252b8f4521fe2913fa278e2c17e3db988996de8d45c685357ec12ba770d321d93f39ed48909b5eb72c26987a0c516857e86 +LLVM.v12.0.1+0.x86_64-w64-mingw32-cxx11.tar.gz/md5/ad4454540db96568b4b5f4fd6ff3d782 +LLVM.v12.0.1+0.x86_64-w64-mingw32-cxx11.tar.gz/sha512/3a22f3ccd38201eda44c8fdc37495eb257027ccc73a1f08c8b6f3b90db218a69363c08b610b2590e7bc33c1aceeb9caf62a8f424599d2a3258c70cc215893489 diff --git a/doc/src/devdocs/llvm.md b/doc/src/devdocs/llvm.md index 7b8334e27ae59..fd14b0020ccbe 100644 --- a/doc/src/devdocs/llvm.md +++ b/doc/src/devdocs/llvm.md @@ -42,7 +42,7 @@ The default version of LLVM is specified in `deps/Versions.make`. You can overri a file called `Make.user` in the top-level directory and adding a line to it such as: ``` -LLVM_VER = 12.0.0 +LLVM_VER = 12.0.1 ``` Besides the LLVM release numerals, you can also use `LLVM_VER = svn` to build against the latest diff --git a/stdlib/libLLVM_jll/Project.toml b/stdlib/libLLVM_jll/Project.toml index 1321496e0695f..f50dc2262c24f 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 = "12.0.0+1" +version = "12.0.1+0" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" From 2ccbb1da726e8997c06bc5253c11a4f03d76eee7 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Sun, 18 Jul 2021 13:22:10 +0200 Subject: [PATCH 60/74] fix ASAN paths (cherry picked from commit 71308eb3981e7df78285d78ffcb5db1536c14a4f) --- Make.inc | 2 +- contrib/asan/Make.user.asan | 10 ++++++---- contrib/asan/build.sh | 4 ++++ 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Make.inc b/Make.inc index 5f8fcab2ede2c..3d61f5255ef1a 100644 --- a/Make.inc +++ b/Make.inc @@ -1390,7 +1390,7 @@ endif # Note: we're passing *FLAGS here computed based on your system compiler to # clang. If that causes you problems, you might want to build and/or run # specific clang-sa-* files with clang explicitly selected: -# make CC=~+/../usr/tools/clang CXX=~+/../usr/tools/clang USECLANG=1 analyzegc +# make CC=~+/../usr/bin/clang CXX=~+/../usr/bin/clang USECLANG=1 analyzegc # make USECLANG=1 clang-sa-* CLANGSA_FLAGS := CLANGSA_CXXFLAGS := diff --git a/contrib/asan/Make.user.asan b/contrib/asan/Make.user.asan index 3bcc34df68323..7277350074188 100644 --- a/contrib/asan/Make.user.asan +++ b/contrib/asan/Make.user.asan @@ -1,10 +1,12 @@ -TOOLCHAIN=$(BUILDROOT)/../toolchain/usr/tools +TOOLCHAIN=$(BUILDROOT)/../toolchain +BINDIR=$(TOOLCHAIN)/usr/bin +TOOLDIR=$(TOOLCHAIN)/usr/tools # use our new toolchain USECLANG=1 -override CC=$(TOOLCHAIN)/clang -override CXX=$(TOOLCHAIN)/clang++ -export ASAN_SYMBOLIZER_PATH=$(TOOLCHAIN)/llvm-symbolizer +override CC=$(BINDIR)/clang +override CXX=$(TOOLDIR)/clang++ +export ASAN_SYMBOLIZER_PATH=$(TOOLDIR)/llvm-symbolizer USE_BINARYBUILDER_LLVM=1 diff --git a/contrib/asan/build.sh b/contrib/asan/build.sh index d124e0a92f1e0..5ef75a78fa2b1 100755 --- a/contrib/asan/build.sh +++ b/contrib/asan/build.sh @@ -41,6 +41,10 @@ fi make -C "$TOOLCHAIN/deps" install-clang install-llvm-tools +# TODO: https://github.com/JuliaPackaging/Yggdrasil/issues/3359 +rm "$TOOLCHAIN/usr/tools/clang++" +ln -s "$TOOLCHAIN/usr/bin/clang" "$TOOLCHAIN/usr/tools/clang++" + echo echo "Building Julia..." From 1016edddf276760a0301975c8cffa9ddf03d273c Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Sun, 18 Jul 2021 13:31:57 +0200 Subject: [PATCH 61/74] fix clang path in analyzegc (cherry picked from commit 8fa8530c84782040ad468d8f8fbad26842df9589) --- src/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Makefile b/src/Makefile index bb38a848ab12f..8da3e4e6687d5 100644 --- a/src/Makefile +++ b/src/Makefile @@ -358,9 +358,9 @@ endif clangsa: $(build_shlibdir)/libGCCheckerPlugin.$(SHLIB_EXT) clang-sa-%: $(SRCDIR)/%.c $(build_shlibdir)/libGCCheckerPlugin.$(SHLIB_EXT) | analyzegc-deps-check - @$(call PRINT_ANALYZE, $(build_depsbindir)/clang --analyze -Xanalyzer -analyzer-werror -Xanalyzer -analyzer-output=text -Xclang -load -Xclang $(build_shlibdir)/libGCCheckerPlugin.$(SHLIB_EXT) $(CLANGSA_FLAGS) $(JCPPFLAGS) $(JCFLAGS) $(DEBUGFLAGS) -Xclang -analyzer-checker=core$(COMMA)julia.GCChecker --analyzer-no-default-checks -fcolor-diagnostics -Werror -x c $<) + @$(call PRINT_ANALYZE, $(build_bindir)/clang --analyze -Xanalyzer -analyzer-werror -Xanalyzer -analyzer-output=text -Xclang -load -Xclang $(build_shlibdir)/libGCCheckerPlugin.$(SHLIB_EXT) $(CLANGSA_FLAGS) $(JCPPFLAGS) $(JCFLAGS) $(DEBUGFLAGS) -Xclang -analyzer-checker=core$(COMMA)julia.GCChecker --analyzer-no-default-checks -fcolor-diagnostics -Werror -x c $<) clang-sa-%: $(SRCDIR)/%.cpp $(build_shlibdir)/libGCCheckerPlugin.$(SHLIB_EXT) | analyzegc-deps-check - @$(call PRINT_ANALYZE, $(build_depsbindir)/clang --analyze -Xanalyzer -analyzer-werror -Xanalyzer -analyzer-output=text -Xclang -load -Xclang $(build_shlibdir)/libGCCheckerPlugin.$(SHLIB_EXT) $(CLANGSA_FLAGS) $(CLANGSA_CXXFLAGS) $(LLVM_CXXFLAGS) $(JCPPFLAGS) $(JCXXFLAGS) $(DEBUGFLAGS) -Xclang -analyzer-checker=core$(COMMA)julia.GCChecker --analyzer-no-default-checks -fcolor-diagnostics -Werror -x c++ $<) + @$(call PRINT_ANALYZE, $(build_bindir)/clang --analyze -Xanalyzer -analyzer-werror -Xanalyzer -analyzer-output=text -Xclang -load -Xclang $(build_shlibdir)/libGCCheckerPlugin.$(SHLIB_EXT) $(CLANGSA_FLAGS) $(CLANGSA_CXXFLAGS) $(LLVM_CXXFLAGS) $(JCPPFLAGS) $(JCXXFLAGS) $(DEBUGFLAGS) -Xclang -analyzer-checker=core$(COMMA)julia.GCChecker --analyzer-no-default-checks -fcolor-diagnostics -Werror -x c++ $<) # Add C files as a target of `analyzegc` analyzegc: $(addprefix clang-sa-,$(RUNTIME_SRCS)) From 693313b2d918b31dd02c92d6f6040f58ae81a871 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Fri, 16 Jul 2021 15:53:46 +0200 Subject: [PATCH 62/74] [Distributed] Allow workers to be started with threading enabled Makes the worker struct threadsafe as well as flushing the GC messages (cherry picked from commit 0c073ccb19ab926e25a1ddb457472f43ef946aeb) --- stdlib/Distributed/src/cluster.jl | 66 +++++++++++++++++---- stdlib/Distributed/src/macros.jl | 10 +--- stdlib/Distributed/src/managers.jl | 2 +- stdlib/Distributed/src/messages.jl | 28 ++++----- stdlib/Distributed/src/remotecall.jl | 46 ++++++++++---- stdlib/Distributed/test/distributed_exec.jl | 1 + stdlib/Distributed/test/threads.jl | 63 ++++++++++++++++++++ 7 files changed, 169 insertions(+), 47 deletions(-) create mode 100644 stdlib/Distributed/test/threads.jl diff --git a/stdlib/Distributed/src/cluster.jl b/stdlib/Distributed/src/cluster.jl index ebe4cac0f3bbe..591ce3f850551 100644 --- a/stdlib/Distributed/src/cluster.jl +++ b/stdlib/Distributed/src/cluster.jl @@ -95,13 +95,14 @@ end @enum WorkerState W_CREATED W_CONNECTED W_TERMINATING W_TERMINATED mutable struct Worker id::Int + msg_lock::Threads.ReentrantLock # Lock for del_msgs, add_msgs, and gcflag del_msgs::Array{Any,1} add_msgs::Array{Any,1} gcflag::Bool state::WorkerState - c_state::Condition # wait for state changes - ct_time::Float64 # creation time - conn_func::Any # used to setup connections lazily + c_state::Threads.Condition # wait for state changes, lock for state + ct_time::Float64 # creation time + conn_func::Any # used to setup connections lazily r_stream::IO w_stream::IO @@ -133,7 +134,7 @@ mutable struct Worker if haskey(map_pid_wrkr, id) return map_pid_wrkr[id] end - w=new(id, [], [], false, W_CREATED, Condition(), time(), conn_func) + w=new(id, Threads.ReentrantLock(), [], [], false, W_CREATED, Threads.Condition(), time(), conn_func) w.initialized = Event() register_worker(w) w @@ -143,12 +144,16 @@ mutable struct Worker end function set_worker_state(w, state) - w.state = state - notify(w.c_state; all=true) + lock(w.c_state) do + w.state = state + notify(w.c_state; all=true) + end end function check_worker_state(w::Worker) + lock(w.c_state) if w.state === W_CREATED + unlock(w.c_state) if !isclusterlazy() if PGRP.topology === :all_to_all # Since higher pids connect with lower pids, the remote worker @@ -168,6 +173,8 @@ function check_worker_state(w::Worker) errormonitor(t) wait_for_conn(w) end + else + unlock(w.c_state) end end @@ -186,13 +193,25 @@ function exec_conn_func(w::Worker) end function wait_for_conn(w) + lock(w.c_state) if w.state === W_CREATED + unlock(w.c_state) timeout = worker_timeout() - (time() - w.ct_time) timeout <= 0 && error("peer $(w.id) has not connected to $(myid())") - @async (sleep(timeout); notify(w.c_state; all=true)) - wait(w.c_state) - w.state === W_CREATED && error("peer $(w.id) didn't connect to $(myid()) within $timeout seconds") + T = Threads.@spawn begin + sleep($timeout) + lock(w.c_state) do + notify(w.c_state; all=true) + end + end + errormonitor(T) + lock(w.c_state) do + wait(w.c_state) + w.state === W_CREATED && error("peer $(w.id) didn't connect to $(myid()) within $timeout seconds") + end + else + unlock(w.c_state) end nothing end @@ -471,6 +490,10 @@ function addprocs_locked(manager::ClusterManager; kwargs...) # The `launch` method should add an object of type WorkerConfig for every # worker launched. It provides information required on how to connect # to it. + + # FIXME: launched should be a Channel, launch_ntfy should be a Threads.Condition + # but both are part of the public interface. This means we currently can't use + # `Threads.@spawn` in the code below. launched = WorkerConfig[] launch_ntfy = Condition() @@ -483,7 +506,10 @@ function addprocs_locked(manager::ClusterManager; kwargs...) while true if isempty(launched) istaskdone(t_launch) && break - @async (sleep(1); notify(launch_ntfy)) + @async begin + sleep(1) + notify(launch_ntfy) + end wait(launch_ntfy) end @@ -636,7 +662,12 @@ function create_worker(manager, wconfig) # require the value of config.connect_at which is set only upon connection completion for jw in PGRP.workers if (jw.id != 1) && (jw.id < w.id) - (jw.state === W_CREATED) && wait(jw.c_state) + # wait for wl to join + lock(jw.c_state) do + if jw.state === W_CREATED + wait(jw.c_state) + end + end push!(join_list, jw) end end @@ -659,7 +690,12 @@ function create_worker(manager, wconfig) end for wl in wlist - (wl.state === W_CREATED) && wait(wl.c_state) + if wl.state === W_CREATED + # wait for wl to join + lock(wl.c_state) do + wait(wl.c_state) + end + end push!(join_list, wl) end end @@ -676,7 +712,11 @@ function create_worker(manager, wconfig) @async manage(w.manager, w.id, w.config, :register) # wait for rr_ntfy_join with timeout timedout = false - @async (sleep($timeout); timedout = true; put!(rr_ntfy_join, 1)) + @async begin + sleep($timeout) + timedout = true + put!(rr_ntfy_join, 1) + end wait(rr_ntfy_join) if timedout error("worker did not connect within $timeout seconds") diff --git a/stdlib/Distributed/src/macros.jl b/stdlib/Distributed/src/macros.jl index 6603d627c3409..24a24f4c08ed4 100644 --- a/stdlib/Distributed/src/macros.jl +++ b/stdlib/Distributed/src/macros.jl @@ -1,14 +1,10 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -let nextidx = 0 +let nextidx = Threads.Atomic{Int}(0) global nextproc function nextproc() - p = -1 - if p == -1 - p = workers()[(nextidx % nworkers()) + 1] - nextidx += 1 - end - p + idx = Threads.atomic_add!(nextidx, 1) + return workers()[(idx % nworkers()) + 1] end end diff --git a/stdlib/Distributed/src/managers.jl b/stdlib/Distributed/src/managers.jl index ce99d85801e17..7ac8007951ddc 100644 --- a/stdlib/Distributed/src/managers.jl +++ b/stdlib/Distributed/src/managers.jl @@ -160,7 +160,7 @@ function launch(manager::SSHManager, params::Dict, launched::Array, launch_ntfy: # Wait for all launches to complete. @sync for (i, (machine, cnt)) in enumerate(manager.machines) let machine=machine, cnt=cnt - @async try + @async try launch_on_machine(manager, $machine, $cnt, params, launched, launch_ntfy) catch e print(stderr, "exception launching on machine $(machine) : $(e)\n") diff --git a/stdlib/Distributed/src/messages.jl b/stdlib/Distributed/src/messages.jl index 47f70e044a2c0..fcba709b4db4a 100644 --- a/stdlib/Distributed/src/messages.jl +++ b/stdlib/Distributed/src/messages.jl @@ -126,22 +126,20 @@ function flush_gc_msgs(w::Worker) if !isdefined(w, :w_stream) return end - w.gcflag = false - new_array = Any[] - msgs = w.add_msgs - w.add_msgs = new_array - if !isempty(msgs) - remote_do(add_clients, w, msgs) - end + lock(w.msg_lock) do + w.gcflag || return # early exit if someone else got to this + w.gcflag = false + msgs = w.add_msgs + w.add_msgs = Any[] + if !isempty(msgs) + remote_do(add_clients, w, msgs) + end - # del_msgs gets populated by finalizers, so be very careful here about ordering of allocations - # XXX: threading requires this to be atomic - new_array = Any[] - msgs = w.del_msgs - w.del_msgs = new_array - if !isempty(msgs) - #print("sending delete of $msgs\n") - remote_do(del_clients, w, msgs) + msgs = w.del_msgs + w.del_msgs = Any[] + if !isempty(msgs) + remote_do(del_clients, w, msgs) + end end end diff --git a/stdlib/Distributed/src/remotecall.jl b/stdlib/Distributed/src/remotecall.jl index 91e5de36736bd..4f0e066ce26e0 100644 --- a/stdlib/Distributed/src/remotecall.jl +++ b/stdlib/Distributed/src/remotecall.jl @@ -247,22 +247,42 @@ function del_clients(pairs::Vector) end end -const any_gc_flag = Condition() +# The task below is coalescing the `flush_gc_msgs` call +# across multiple producers, see `send_del_client`, +# and `send_add_client`. +# XXX: Is this worth the additional complexity? +# `flush_gc_msgs` has to iterate over all connected workers. +const any_gc_flag = Threads.Condition() function start_gc_msgs_task() - errormonitor(@async while true - wait(any_gc_flag) - flush_gc_msgs() - end) + errormonitor( + Threads.@spawn begin + while true + lock(any_gc_flag) do + wait(any_gc_flag) + flush_gc_msgs() # handles throws internally + end + end + end + ) end +# Function can be called within a finalizer function send_del_client(rr) if rr.where == myid() del_client(rr) elseif id_in_procs(rr.where) # process only if a valid worker w = worker_from_id(rr.where)::Worker - push!(w.del_msgs, (remoteref_id(rr), myid())) - w.gcflag = true - notify(any_gc_flag) + msg = (remoteref_id(rr), myid()) + # We cannot acquire locks from finalizers + Threads.@spawn begin + lock(w.msg_lock) do + push!(w.del_msgs, msg) + w.gcflag = true + end + lock(any_gc_flag) do + notify(any_gc_flag) + end + end end end @@ -288,9 +308,13 @@ function send_add_client(rr::AbstractRemoteRef, i) # to the processor that owns the remote ref. it will add_client # itself inside deserialize(). w = worker_from_id(rr.where) - push!(w.add_msgs, (remoteref_id(rr), i)) - w.gcflag = true - notify(any_gc_flag) + lock(w.msg_lock) do + push!(w.add_msgs, (remoteref_id(rr), i)) + w.gcflag = true + end + lock(any_gc_flag) do + notify(any_gc_flag) + end end end diff --git a/stdlib/Distributed/test/distributed_exec.jl b/stdlib/Distributed/test/distributed_exec.jl index 606b7fa81c3e7..547b035e8e6b9 100644 --- a/stdlib/Distributed/test/distributed_exec.jl +++ b/stdlib/Distributed/test/distributed_exec.jl @@ -1689,4 +1689,5 @@ include("splitrange.jl") # Run topology tests last after removing all workers, since a given # cluster at any time only supports a single topology. rmprocs(workers()) +include("threads.jl") include("topology.jl") diff --git a/stdlib/Distributed/test/threads.jl b/stdlib/Distributed/test/threads.jl new file mode 100644 index 0000000000000..57d99b7ea056c --- /dev/null +++ b/stdlib/Distributed/test/threads.jl @@ -0,0 +1,63 @@ +using Test +using Distributed, Base.Threads +using Base.Iterators: product + +exeflags = ("--startup-file=no", + "--check-bounds=yes", + "--depwarn=error", + "--threads=2") + +function call_on(f, wid, tid) + remotecall(wid) do + t = Task(f) + ccall(:jl_set_task_tid, Cvoid, (Any, Cint), t, tid - 1) + schedule(t) + @assert threadid(t) == tid + t + end +end + +# Run function on process holding the data to only serialize the result of f. +# This becomes useful for things that cannot be serialized (e.g. running tasks) +# or that would be unnecessarily big if serialized. +fetch_from_owner(f, rr) = remotecall_fetch(f ∘ fetch, rr.where, rr) + +isdone(rr) = fetch_from_owner(istaskdone, rr) +isfailed(rr) = fetch_from_owner(istaskfailed, rr) + +@testset "RemoteChannel allows put!/take! from thread other than 1" begin + ws = ts = product(1:2, 1:2) + @testset "from worker $w1 to $w2 via 1" for (w1, w2) in ws + @testset "from thread $w1.$t1 to $w2.$t2" for (t1, t2) in ts + # We want (the default) lazyness, so that we wait for `Worker.c_state`! + procs_added = addprocs(2; exeflags, lazy=true) + @everywhere procs_added using Base.Threads + + p1 = procs_added[w1] + p2 = procs_added[w2] + chan_id = first(procs_added) + chan = RemoteChannel(chan_id) + send = call_on(p1, t1) do + put!(chan, nothing) + end + recv = call_on(p2, t2) do + take!(chan) + end + + # Wait on the spawned tasks on the owner + @sync begin + Threads.@spawn fetch_from_owner(wait, recv) + Threads.@spawn fetch_from_owner(wait, send) + end + + # Check the tasks + @test isdone(send) + @test isdone(recv) + + @test !isfailed(send) + @test !isfailed(recv) + + rmprocs(procs_added) + end + end +end From f3da8d9cc6830b5b119e302112a6ea398adf3731 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Mon, 19 Jul 2021 22:42:45 +0200 Subject: [PATCH 63/74] fixup to pull request #38405 (#41641) (cherry picked from commit 5af1cf0faf10308857f319b17432b007e318516b) --- stdlib/Distributed/src/cluster.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/stdlib/Distributed/src/cluster.jl b/stdlib/Distributed/src/cluster.jl index 591ce3f850551..52400a129efb4 100644 --- a/stdlib/Distributed/src/cluster.jl +++ b/stdlib/Distributed/src/cluster.jl @@ -690,10 +690,10 @@ function create_worker(manager, wconfig) end for wl in wlist - if wl.state === W_CREATED - # wait for wl to join - lock(wl.c_state) do - wait(wl.c_state) + lock(wl.c_state) do + if wl.state === W_CREATED + # wait for wl to join + wait(wl.c_state) end end push!(join_list, wl) From ac5b266a299879a5e390b690cb8ada499414c123 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Fri, 2 Jul 2021 10:28:41 -0400 Subject: [PATCH 64/74] deprecate unsafe_length for simply length (#40382) This seems to be a fairly arbitrary case for throwing exceptions, when the user might often use this value in arithmetic afterwards, which is not checked. It leads to awkward complexity in the API however, where it may be unclear which function to reach for, with no particular justification for why a particular usage is "safe". And it inhibits optimization and performance due to the additional checks and error cases (and is not even entirely type-stable). (cherry picked from commit 3eefaf0a52d1f537c512282a3027ead8e5e4f44e) --- NEWS.md | 4 + base/abstractarray.jl | 15 +- base/broadcast.jl | 2 +- base/checked.jl | 12 +- base/deprecated.jl | 3 + base/indices.jl | 8 +- base/multidimensional.jl | 2 +- base/range.jl | 147 +++++++++++++------ base/subarray.jl | 10 +- doc/src/base/collections.md | 1 + stdlib/Dates/test/ranges.jl | 2 +- test/ranges.jl | 217 +++++++++++++++++++++-------- test/testhelpers/Furlongs.jl | 15 +- test/testhelpers/InfiniteArrays.jl | 8 +- test/testhelpers/OffsetArrays.jl | 1 - 15 files changed, 307 insertions(+), 140 deletions(-) diff --git a/NEWS.md b/NEWS.md index 7b2d16c2d2dc5..4a4b30f6a0db1 100644 --- a/NEWS.md +++ b/NEWS.md @@ -144,6 +144,10 @@ Standard library changes * `replace(::String)` now accepts multiple patterns, which will be applied left-to-right simultaneously, so only one pattern will be applied to any character, and the patterns will only be applied to the input text, not the replacements ([#40484]). +* The `length` function on certain ranges of certain specific element types no longer checks for integer + overflow in most cases. The new function `checked_length` is now available, which will try to use checked + arithmetic to error if the result may be wrapping. Or use a package such as SaferIntegers.jl when + constructing the range. ([#40382]) #### Package Manager diff --git a/base/abstractarray.jl b/base/abstractarray.jl index f5eb075241dc6..f622b07d56e44 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -116,9 +116,6 @@ axes1(A::AbstractArray{<:Any,0}) = OneTo(1) axes1(A::AbstractArray) = (@_inline_meta; axes(A)[1]) axes1(iter) = oneto(length(iter)) -unsafe_indices(A) = axes(A) -unsafe_indices(r::AbstractRange) = (oneto(unsafe_length(r)),) # Ranges use checked_sub for size - """ keys(a::AbstractArray) @@ -580,14 +577,14 @@ end function trailingsize(inds::Indices, n) s = 1 for i=n:length(inds) - s *= unsafe_length(inds[i]) + s *= length(inds[i]) end return s end # This version is type-stable even if inds is heterogeneous function trailingsize(inds::Indices) @_inline_meta - prod(map(unsafe_length, inds)) + prod(map(length, inds)) end ## Bounds checking ## @@ -688,7 +685,7 @@ function checkbounds_indices(::Type{Bool}, ::Tuple{}, I::Tuple) @_inline_meta checkindex(Bool, OneTo(1), I[1])::Bool & checkbounds_indices(Bool, (), tail(I)) end -checkbounds_indices(::Type{Bool}, IA::Tuple, ::Tuple{}) = (@_inline_meta; all(x->unsafe_length(x)==1, IA)) +checkbounds_indices(::Type{Bool}, IA::Tuple, ::Tuple{}) = (@_inline_meta; all(x->length(x)==1, IA)) checkbounds_indices(::Type{Bool}, ::Tuple{}, ::Tuple{}) = true throw_boundserror(A, I) = (@_noinline_meta; throw(BoundsError(A, I))) @@ -2590,8 +2587,8 @@ function _sub2ind_recurse(inds, L, ind, i::Integer, I::Integer...) end nextL(L, l::Integer) = L*l -nextL(L, r::AbstractUnitRange) = L*unsafe_length(r) -nextL(L, r::Slice) = L*unsafe_length(r.indices) +nextL(L, r::AbstractUnitRange) = L*length(r) +nextL(L, r::Slice) = L*length(r.indices) offsetin(i, l::Integer) = i-1 offsetin(i, r::AbstractUnitRange) = i-first(r) @@ -2617,7 +2614,7 @@ end _lookup(ind, d::Integer) = ind+1 _lookup(ind, r::AbstractUnitRange) = ind+first(r) _div(ind, d::Integer) = div(ind, d), 1, d -_div(ind, r::AbstractUnitRange) = (d = unsafe_length(r); (div(ind, d), first(r), d)) +_div(ind, r::AbstractUnitRange) = (d = length(r); (div(ind, d), first(r), d)) # Vectorized forms function _sub2ind(inds::Indices{1}, I1::AbstractVector{T}, I::AbstractVector{T}...) where T<:Integer diff --git a/base/broadcast.jl b/base/broadcast.jl index 7c87fef3f19e6..c6651e28489a3 100644 --- a/base/broadcast.jl +++ b/base/broadcast.jl @@ -566,7 +566,7 @@ an `Int`. """ Base.@propagate_inbounds newindex(arg, I::CartesianIndex) = CartesianIndex(_newindex(axes(arg), I.I)) Base.@propagate_inbounds newindex(arg, I::Integer) = CartesianIndex(_newindex(axes(arg), (I,))) -Base.@propagate_inbounds _newindex(ax::Tuple, I::Tuple) = (ifelse(Base.unsafe_length(ax[1])==1, ax[1][1], I[1]), _newindex(tail(ax), tail(I))...) +Base.@propagate_inbounds _newindex(ax::Tuple, I::Tuple) = (ifelse(length(ax[1]) == 1, ax[1][1], I[1]), _newindex(tail(ax), tail(I))...) Base.@propagate_inbounds _newindex(ax::Tuple{}, I::Tuple) = () Base.@propagate_inbounds _newindex(ax::Tuple, I::Tuple{}) = (ax[1][1], _newindex(tail(ax), ())...) Base.@propagate_inbounds _newindex(ax::Tuple{}, I::Tuple{}) = () diff --git a/base/checked.jl b/base/checked.jl index 840015861923f..ba23d4c5acd2b 100644 --- a/base/checked.jl +++ b/base/checked.jl @@ -6,14 +6,14 @@ module Checked export checked_neg, checked_abs, checked_add, checked_sub, checked_mul, checked_div, checked_rem, checked_fld, checked_mod, checked_cld, - add_with_overflow, sub_with_overflow, mul_with_overflow + checked_length, add_with_overflow, sub_with_overflow, mul_with_overflow import Core.Intrinsics: checked_sadd_int, checked_ssub_int, checked_smul_int, checked_sdiv_int, checked_srem_int, checked_uadd_int, checked_usub_int, checked_umul_int, checked_udiv_int, checked_urem_int -import ..no_op_err, ..@_inline_meta, ..@_noinline_meta +import ..no_op_err, ..@_inline_meta, ..@_noinline_meta, ..checked_length # define promotion behavior for checked operations checked_add(x::Integer, y::Integer) = checked_add(promote(x,y)...) @@ -349,4 +349,12 @@ The overflow protection may impose a perceptible performance penalty. """ checked_cld(x::T, y::T) where {T<:Integer} = cld(x, y) # Base.cld already checks +""" + Base.checked_length(r) + +Calculates `length(r)`, but may check for overflow errors where applicable when +the result doesn't fit into `Union{Integer(eltype(r)),Int}`. +""" +checked_length(r) = length(r) # for most things, length doesn't error + end diff --git a/base/deprecated.jl b/base/deprecated.jl index c2a717a403a90..92d07fadbaa77 100644 --- a/base/deprecated.jl +++ b/base/deprecated.jl @@ -246,6 +246,9 @@ const Any16{N} = Tuple{Any,Any,Any,Any,Any,Any,Any,Any, const All16{T,N} = Tuple{T,T,T,T,T,T,T,T, T,T,T,T,T,T,T,T,Vararg{T,N}} +@deprecate unsafe_indices(A) axes(A) false +@deprecate unsafe_length(r) length(r) false + # END 1.6 deprecations # BEGIN 1.7 deprecations diff --git a/base/indices.jl b/base/indices.jl index ef9e2c52ca6a3..817d9d435522b 100644 --- a/base/indices.jl +++ b/base/indices.jl @@ -352,17 +352,14 @@ struct Slice{T<:AbstractUnitRange} <: AbstractUnitRange{Int} end Slice(S::Slice) = S axes(S::Slice) = (IdentityUnitRange(S.indices),) -unsafe_indices(S::Slice) = (IdentityUnitRange(S.indices),) axes1(S::Slice) = IdentityUnitRange(S.indices) axes(S::Slice{<:OneTo}) = (S.indices,) -unsafe_indices(S::Slice{<:OneTo}) = (S.indices,) axes1(S::Slice{<:OneTo}) = S.indices first(S::Slice) = first(S.indices) last(S::Slice) = last(S.indices) size(S::Slice) = (length(S.indices),) length(S::Slice) = length(S.indices) -unsafe_length(S::Slice) = unsafe_length(S.indices) getindex(S::Slice, i::Int) = (@_inline_meta; @boundscheck checkbounds(S, i); i) getindex(S::Slice, i::AbstractUnitRange{<:Integer}) = (@_inline_meta; @boundscheck checkbounds(S, i); i) getindex(S::Slice, i::StepRange{<:Integer}) = (@_inline_meta; @boundscheck checkbounds(S, i); i) @@ -383,17 +380,14 @@ end IdentityUnitRange(S::IdentityUnitRange) = S # IdentityUnitRanges are offset and thus have offset axes, so they are their own axes axes(S::IdentityUnitRange) = (S,) -unsafe_indices(S::IdentityUnitRange) = (S,) axes1(S::IdentityUnitRange) = S axes(S::IdentityUnitRange{<:OneTo}) = (S.indices,) -unsafe_indices(S::IdentityUnitRange{<:OneTo}) = (S.indices,) axes1(S::IdentityUnitRange{<:OneTo}) = S.indices first(S::IdentityUnitRange) = first(S.indices) last(S::IdentityUnitRange) = last(S.indices) size(S::IdentityUnitRange) = (length(S.indices),) length(S::IdentityUnitRange) = length(S.indices) -unsafe_length(S::IdentityUnitRange) = unsafe_length(S.indices) getindex(S::IdentityUnitRange, i::Int) = (@_inline_meta; @boundscheck checkbounds(S, i); i) getindex(S::IdentityUnitRange, i::AbstractUnitRange{<:Integer}) = (@_inline_meta; @boundscheck checkbounds(S, i); i) getindex(S::IdentityUnitRange, i::StepRange{<:Integer}) = (@_inline_meta; @boundscheck checkbounds(S, i); i) @@ -479,7 +473,7 @@ convert(::Type{LinearIndices{N,R}}, inds::LinearIndices{N}) where {N,R} = # AbstractArray implementation IndexStyle(::Type{<:LinearIndices}) = IndexLinear() axes(iter::LinearIndices) = map(axes1, iter.indices) -size(iter::LinearIndices) = map(unsafe_length, iter.indices) +size(iter::LinearIndices) = map(length, iter.indices) function getindex(iter::LinearIndices, i::Int) @_inline_meta @boundscheck checkbounds(iter, i) diff --git a/base/multidimensional.jl b/base/multidimensional.jl index 2f277af36cdc1..8104cddb34387 100644 --- a/base/multidimensional.jl +++ b/base/multidimensional.jl @@ -849,7 +849,7 @@ function _unsafe_getindex(::IndexStyle, A::AbstractArray, I::Vararg{Union{Real, # This is specifically not inlined to prevent excessive allocations in type unstable code shape = index_shape(I...) dest = similar(A, shape) - map(unsafe_length, axes(dest)) == map(unsafe_length, shape) || throw_checksize_error(dest, shape) + map(length, axes(dest)) == map(length, shape) || throw_checksize_error(dest, shape) _unsafe_getindex!(dest, A, I...) # usually a generated function, don't allow it to impact inference result return dest end diff --git a/base/range.jl b/base/range.jl index 9e6d6c0946250..e6a53e30892f3 100644 --- a/base/range.jl +++ b/base/range.jl @@ -585,9 +585,11 @@ end ## interface implementations +length(r::AbstractRange) = error("length implementation missing") # catch mistakes size(r::AbstractRange) = (length(r),) isempty(r::StepRange) = + # steprange_last_empty(r.start, r.step, r.stop) == r.stop (r.start != r.stop) & ((r.step > zero(r.step)) != (r.stop > r.start)) isempty(r::AbstractUnitRange) = first(r) > last(r) isempty(r::StepRangeLen) = length(r) == 0 @@ -614,7 +616,7 @@ julia> step(range(2.5, stop=10.9, length=85)) ``` """ step(r::StepRange) = r.step -step(r::AbstractUnitRange{T}) where{T} = oneunit(T) - zero(T) +step(r::AbstractUnitRange{T}) where {T} = oneunit(T) - zero(T) step(r::StepRangeLen) = r.step step(r::StepRangeLen{T}) where {T<:AbstractFloat} = T(r.step) step(r::LinRange) = (last(r)-first(r))/r.lendiv @@ -622,60 +624,127 @@ step(r::LinRange) = (last(r)-first(r))/r.lendiv step_hp(r::StepRangeLen) = r.step step_hp(r::AbstractRange) = step(r) -unsafe_length(r::AbstractRange) = length(r) # generic fallback - -function unsafe_length(r::StepRange) - n = Integer(div((r.stop - r.start) + r.step, r.step)) - isempty(r) ? zero(n) : n -end -length(r::StepRange) = unsafe_length(r) -unsafe_length(r::AbstractUnitRange) = Integer(last(r) - first(r) + step(r)) -unsafe_length(r::OneTo) = Integer(r.stop - zero(r.stop)) -length(r::AbstractUnitRange) = unsafe_length(r) -length(r::OneTo) = unsafe_length(r) -length(r::StepRangeLen) = r.len -length(r::LinRange) = r.len +axes(r::AbstractRange) = (oneto(length(r)),) # Needed to fold the `firstindex` call in SimdLoop.simd_index firstindex(::UnitRange) = 1 firstindex(::StepRange) = 1 firstindex(::LinRange) = 1 -function length(r::StepRange{T}) where T<:Union{Int,UInt,Int64,UInt64,Int128,UInt128} - isempty(r) && return zero(T) - if r.step > 1 - return checked_add(convert(T, div(unsigned(r.stop - r.start), r.step)), one(T)) - elseif r.step < -1 - return checked_add(convert(T, div(unsigned(r.start - r.stop), -r.step)), one(T)) - elseif r.step > 0 - return checked_add(div(checked_sub(r.stop, r.start), r.step), one(T)) +# n.b. checked_length for these is defined iff checked_add and checked_sub are +# defined between the relevant types +function checked_length(r::OrdinalRange{T}) where T + s = step(r) + # s != 0, by construction, but avoids the division error later + start = first(r) + if s == zero(s) || isempty(r) + return Integer(start - start + zero(s)) + end + stop = last(r) + if isless(s, zero(s)) + diff = checked_sub(start, stop) + s = -s else - return checked_add(div(checked_sub(r.start, r.stop), -r.step), one(T)) + diff = checked_sub(stop, start) end + a = Integer(div(diff, s)) + return checked_add(a, one(a)) end -function length(r::AbstractUnitRange{T}) where T<:Union{Int,Int64,Int128} +function checked_length(r::AbstractUnitRange{T}) where T + # compiler optimization: remove dead cases from above + if isempty(r) + return Integer(first(r) - first(r)) + end + a = Integer(checked_add(checked_sub(last(r), first(r)))) + return checked_add(a, one(a)) +end + +function length(r::OrdinalRange{T}) where T + s = step(r) + # s != 0, by construction, but avoids the division error later + start = first(r) + if s == zero(s) || isempty(r) + return Integer(start - start + zero(s)) + end + stop = last(r) + if isless(s, zero(s)) + diff = start - stop + s = -s + else + diff = stop - start + end + a = Integer(div(diff, s)) + return a + one(a) +end + + +function length(r::AbstractUnitRange{T}) where T @_inline_meta - checked_add(checked_sub(last(r), first(r)), one(T)) + a = Integer(last(r) - first(r)) # even when isempty, by construction (with overflow) + return a + one(a) end -length(r::OneTo{T}) where {T<:Union{Int,Int64}} = T(r.stop) -length(r::AbstractUnitRange{T}) where {T<:Union{UInt,UInt64,UInt128}} = - r.stop < r.start ? zero(T) : checked_add(last(r) - first(r), one(T)) +length(r::OneTo) = Integer(r.stop - zero(r.stop)) +length(r::StepRangeLen) = r.len +length(r::LinRange) = r.len -# some special cases to favor default Int type -let smallint = (Int === Int64 ? - Union{Int8,UInt8,Int16,UInt16,Int32,UInt32} : - Union{Int8,UInt8,Int16,UInt16}) - global length - - function length(r::StepRange{<:smallint}) - isempty(r) && return Int(0) - div(Int(r.stop)+Int(r.step) - Int(r.start), Int(r.step)) +let bigints = Union{Int, UInt, Int64, UInt64, Int128, UInt128} + global length, checked_length + # compile optimization for which promote_type(T, Int) == T + length(r::OneTo{T}) where {T<:bigints} = r.stop + # slightly more accurate length and checked_length in extreme cases + # (near typemax) for types with known `unsigned` functions + function length(r::OrdinalRange{T}) where T<:bigints + s = step(r) + s == zero(s) && return zero(T) # unreachable, by construction, but avoids the error case here later + isempty(r) && return zero(T) + diff = last(r) - first(r) + # if |s| > 1, diff might have overflowed, but unsigned(diff)÷s should + # therefore still be valid (if the result is representable at all) + # n.b. !(s isa T) + if s isa Unsigned || -1 <= s <= 1 || s == -s + a = div(diff, s) + elseif s < 0 + a = div(unsigned(-diff), -s) % typeof(diff) + else + a = div(unsigned(diff), s) % typeof(diff) + end + return Integer(a) + one(a) + end + function checked_length(r::OrdinalRange{T}) where T<:bigints + s = step(r) + s == zero(s) && return zero(T) # unreachable, by construction, but avoids the error case here later + isempty(r) && return zero(T) + stop, start = last(r), first(r) + # n.b. !(s isa T) + if s > 1 + diff = stop - start + a = convert(T, div(unsigned(diff), s)) + elseif s < -1 + diff = start - stop + a = convert(T, div(unsigned(diff), -s)) + elseif s > 0 + a = div(checked_sub(stop, start), s) + else + a = div(checked_sub(start, stop), -s) + end + return checked_add(a, one(a)) end +end - length(r::AbstractUnitRange{<:smallint}) = Int(last(r)) - Int(first(r)) + 1 - length(r::OneTo{<:smallint}) = Int(r.stop) +# some special cases to favor default Int type +let smallints = (Int === Int64 ? + Union{Int8, UInt8, Int16, UInt16, Int32, UInt32} : + Union{Int8, UInt8, Int16, UInt16}) + global length, checked_length + # n.b. !(step isa T) + length(r::OrdinalRange{<:smallints}) = div(Int(last(r)) - Int(first(r)), step(r)) + 1 + length(r::AbstractUnitRange{<:smallints}) = Int(last(r)) - Int(first(r)) + 1 + length(r::OneTo{<:smallints}) = Int(r.stop) + checked_length(r::OrdinalRange{<:smallints}) = length(r) + checked_length(r::AbstractUnitRange{<:smallints}) = length(r) + checked_length(r::OneTo{<:smallints}) = length(r) end first(r::OrdinalRange{T}) where {T} = convert(T, r.start) diff --git a/base/subarray.jl b/base/subarray.jl index 32262058cb55b..89a4db4d65790 100644 --- a/base/subarray.jl +++ b/base/subarray.jl @@ -60,7 +60,7 @@ viewindexing(I::Tuple{Vararg{Any}}) = IndexCartesian() viewindexing(I::Tuple{AbstractArray, Vararg{Any}}) = IndexCartesian() # Simple utilities -size(V::SubArray) = (@_inline_meta; map(unsafe_length, axes(V))) +size(V::SubArray) = (@_inline_meta; map(length, axes(V))) similar(V::SubArray, T::Type, dims::Dims) = similar(V.parent, T, dims) @@ -362,7 +362,7 @@ compute_stride1(parent::AbstractArray, I::NTuple{N,Any}) where {N} = compute_stride1(s, inds, I::Tuple{}) = s compute_stride1(s, inds, I::Tuple{Vararg{ScalarIndex}}) = s compute_stride1(s, inds, I::Tuple{ScalarIndex, Vararg{Any}}) = - (@_inline_meta; compute_stride1(s*unsafe_length(inds[1]), tail(inds), tail(I))) + (@_inline_meta; compute_stride1(s*length(inds[1]), tail(inds), tail(I))) compute_stride1(s, inds, I::Tuple{AbstractRange, Vararg{Any}}) = s*step(I[1]) compute_stride1(s, inds, I::Tuple{Slice, Vararg{Any}}) = s compute_stride1(s, inds, I::Tuple{Any, Vararg{Any}}) = throw(ArgumentError("invalid strided index type $(typeof(I[1]))")) @@ -407,12 +407,12 @@ end function compute_linindex(f, s, IP::Tuple, I::Tuple{ScalarIndex, Vararg{Any}}) @_inline_meta Δi = I[1]-first(IP[1]) - compute_linindex(f + Δi*s, s*unsafe_length(IP[1]), tail(IP), tail(I)) + compute_linindex(f + Δi*s, s*length(IP[1]), tail(IP), tail(I)) end function compute_linindex(f, s, IP::Tuple, I::Tuple{Any, Vararg{Any}}) @_inline_meta Δi = first(I[1])-first(IP[1]) - compute_linindex(f + Δi*s, s*unsafe_length(IP[1]), tail(IP), tail(I)) + compute_linindex(f + Δi*s, s*length(IP[1]), tail(IP), tail(I)) end compute_linindex(f, s, IP::Tuple, I::Tuple{}) = f @@ -447,5 +447,5 @@ _indices_sub(::Real, I...) = (@_inline_meta; _indices_sub(I...)) _indices_sub() = () function _indices_sub(i1::AbstractArray, I...) @_inline_meta - (unsafe_indices(i1)..., _indices_sub(I...)...) + (axes(i1)..., _indices_sub(I...)...) end diff --git a/doc/src/base/collections.md b/doc/src/base/collections.md index f8ef12071171a..84e5702e0e396 100644 --- a/doc/src/base/collections.md +++ b/doc/src/base/collections.md @@ -66,6 +66,7 @@ Base.LinRange Base.isempty Base.empty! Base.length +Base.checked_length ``` Fully implemented by: diff --git a/stdlib/Dates/test/ranges.jl b/stdlib/Dates/test/ranges.jl index 6eb6371376867..52416fc95ec0c 100644 --- a/stdlib/Dates/test/ranges.jl +++ b/stdlib/Dates/test/ranges.jl @@ -515,7 +515,7 @@ end @test length(Dates.Year(1):Dates.Year(1):Dates.Year(10)) == 10 @test length(Dates.Year(10):Dates.Year(-1):Dates.Year(1)) == 10 @test length(Dates.Year(10):Dates.Year(-2):Dates.Year(1)) == 5 -@test_throws OverflowError length(typemin(Dates.Year):Dates.Year(1):typemax(Dates.Year)) +@test length(typemin(Dates.Year):Dates.Year(1):typemax(Dates.Year)) == 0 # overflow @test_throws MethodError Dates.Date(0):Dates.DateTime(2000) @test_throws MethodError Dates.Date(0):Dates.Year(10) @test length(range(Dates.Date(2000), step=Dates.Day(1), length=366)) == 366 diff --git a/test/ranges.jl b/test/ranges.jl index 783120c361bcd..b622fc05b3ca6 100644 --- a/test/ranges.jl +++ b/test/ranges.jl @@ -1,5 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +using Base.Checked: checked_length + @testset "range construction" begin @test_throws ArgumentError range(start=1, step=1, stop=2, length=10) @test_throws ArgumentError range(start=1, step=1, stop=10, length=11) @@ -267,22 +269,28 @@ end end end @testset "length" begin - @test length(.1:.1:.3) == 3 - @test length(1.1:1.1:3.3) == 3 - @test length(1.1:1.3:3) == 2 - @test length(1:1:1.8) == 1 - @test length(1:.2:2) == 6 - @test length(1.:.2:2.) == 6 - @test length(2:-.2:1) == 6 - @test length(2.:-.2:1.) == 6 - @test length(2:.2:1) == 0 + @test length(.1:.1:.3) == checked_length(.1:.1:.3) == 3 + @test length(1.1:1.1:3.3) == checked_length(1.1:1.1:3.3) == 3 + @test length(1.1:1.3:3) == checked_length(1.1:1.3:3) == 2 + @test length(1:1:1.8) == checked_length(1:1:1.8) == 1 + @test length(1:.2:2) == checked_length(1:.2:2) == 6 + @test length(1.:.2:2.) == checked_length(1.:.2:2.) == 6 + @test length(2:-.2:1) == checked_length(2:-.2:1) == 6 + @test length(2.:-.2:1.) == checked_length(2.:-.2:1.) == 6 + @test length(2:.2:1) == checked_length(2:.2:1) == 0 @test length(2.:.2:1.) == 0 - @test length(1:0) == 0 - @test length(0.0:-0.5) == 0 - @test length(1:2:0) == 0 - @test length(Char(0):Char(0x001fffff)) == 2097152 - @test length(typemax(UInt64)//one(UInt64):1:typemax(UInt64)//one(UInt64)) == 1 + @test length(1:0) == checked_length(1:0) == 0 + @test length(0.0:-0.5) == checked_length(0.0:-0.5) == 0 + @test length(1:2:0) == checked_length(1:2:0) == 0 + let r = Char(0):Char(0x001fffff) + @test length(r) == 2097152 + @test_throws MethodError checked_length(r) == 2097152 # this would work if checked_sub is defined on Char + end + let r = typemax(UInt64)//one(UInt64):1:typemax(UInt64)//one(UInt64) + @test length(r) == 1 + @test_throws MethodError checked_length(r) == 1 # this would work if checked_sub is defined on Rational + end end @testset "keys/values" begin keytype_is_correct(r) = keytype(r) == eltype(keys(r)) @@ -501,22 +509,41 @@ for a=AbstractRange[3:6, 0:2:10], b=AbstractRange[0:1, 2:-1:0] end # avoiding intermediate overflow (#5065) -@test length(1:4:typemax(Int)) == div(typemax(Int),4) + 1 +@test length(1:4:typemax(Int)) == div(typemax(Int), 4) + 1 +@test checked_length(1:4:typemax(Int)) == div(typemax(Int), 4) + 1 # computed exactly in modulo arithmetic @testset "overflow in length" begin - Tset = Int === Int64 ? (Int,UInt,Int128,UInt128) : - (Int,UInt,Int64,UInt64,Int128, UInt128) + Tset = Int === Int64 ? (Int, UInt, Int128, UInt128) : + (Int, UInt, Int64, UInt64, Int128, UInt128) for T in Tset - @test_throws OverflowError length(zero(T):typemax(T)) - @test_throws OverflowError length(typemin(T):typemax(T)) - @test_throws OverflowError length(zero(T):one(T):typemax(T)) - @test_throws OverflowError length(typemin(T):one(T):typemax(T)) + @test length(zero(T):typemax(T)) == typemin(T) + @test length(typemin(T):typemax(T)) == T(0) + @test length(zero(T):one(T):typemax(T)) == typemin(T) + @test length(typemin(T):one(T):typemax(T)) == T(0) + @test_throws OverflowError checked_length(zero(T):typemax(T)) + @test_throws OverflowError checked_length(typemin(T):typemax(T)) + @test_throws OverflowError checked_length(zero(T):one(T):typemax(T)) + @test_throws OverflowError checked_length(typemin(T):one(T):typemax(T)) + @test length(one(T):typemax(T)) == checked_length(one(T):typemax(T)) == typemax(T) if T <: Signed - @test_throws OverflowError length(-one(T):typemax(T)-one(T)) - @test_throws OverflowError length(-one(T):one(T):typemax(T)-one(T)) + @test length(-one(T):typemax(T)-one(T)) == typemin(T) + @test length(-one(T):one(T):typemax(T)-one(T)) == typemin(T) + @test length(-one(T):typemax(T)) == typemin(T) + T(1) + @test length(zero(T):typemin(T):typemin(T)) == 2 + @test length(one(T):typemin(T):typemin(T)) == 2 + @test length(typemax(T):typemin(T):typemin(T)) == 2 + @test length(-one(T):typemin(T):typemin(T)) == 1 + @test length(zero(T):typemin(T):zero(T)) == 1 + @test length(zero(T):typemin(T):one(T)) == 0 + @test_throws OverflowError checked_length(-one(T):typemax(T)-one(T)) + @test_throws OverflowError checked_length(-one(T):one(T):typemax(T)-one(T)) + @test_throws InexactError checked_length(zero(T):typemin(T):typemin(T)) == 2 # this can be improved + @test_throws InexactError checked_length(one(T):typemin(T):typemin(T)) == 2 # this can be improved + @test_throws InexactError checked_length(typemax(T):typemin(T):typemin(T)) == 2 # this can be improved end end end + @testset "loops involving typemin/typemax" begin n = 0 s = 0 @@ -871,32 +898,45 @@ end end # issue #2959 @test 1.0:1.5 == 1.0:1.0:1.5 == 1.0:1.0 -#@test 1.0:(.3-.1)/.1 == 1.0:2.0 +@test_broken 1.0:(.3-.1)/.1 == 1.0:2.0 # (this is just shy of 2.0) @testset "length with typemin/typemax" begin - let r = typemin(Int64):2:typemax(Int64), s = typemax(Int64):-2:typemin(Int64) + let r = typemin(Int64):2:typemax(Int64) @test first(r) == typemin(Int64) - @test last(r) == (typemax(Int64)-1) - @test_throws OverflowError length(r) - - @test first(s) == typemax(Int64) - @test last(s) == (typemin(Int64)+1) - @test_throws OverflowError length(s) + @test last(r) == typemax(Int64) - 1 + @test length(r) == typemin(Int64) + @test_throws OverflowError checked_length(r) + end + let r = typemax(Int64):-2:typemin(Int64) + @test first(r) == typemax(Int64) + @test last(r) == typemin(Int64) + 1 + @test length(r) == typemin(Int64) + @test_throws OverflowError checked_length(r) end - @test length(typemin(Int64):3:typemax(Int64)) == 6148914691236517206 - @test length(typemax(Int64):-3:typemin(Int64)) == 6148914691236517206 + let r = typemin(Int64):3:typemax(Int64) + @test length(r) == checked_length(r) == 6148914691236517206 + end + let r = typemax(Int64):-3:typemin(Int64) + @test length(r) == checked_length(r) == 6148914691236517206 + end for s in 3:100 - @test length(typemin(Int):s:typemax(Int)) == length(big(typemin(Int)):big(s):big(typemax(Int))) - @test length(typemax(Int):-s:typemin(Int)) == length(big(typemax(Int)):big(-s):big(typemin(Int))) + r = typemin(Int):s:typemax(Int) + br = big(typemin(Int)):big(s):big(typemax(Int)) + @test length(r) == checked_length(r) == length(br) + + r = typemax(Int):-s:typemin(Int) + br = big(typemax(Int)):big(-s):big(typemin(Int)) + @test length(r) == checked_length(r) == length(br) end - @test length(UInt(1):UInt(1):UInt(0)) == 0 - @test length(typemax(UInt):UInt(1):(typemax(UInt)-1)) == 0 - @test length(typemax(UInt):UInt(2):(typemax(UInt)-1)) == 0 - @test length((typemin(Int)+3):5:(typemin(Int)+1)) == 0 + @test length(UInt(1):UInt(1):UInt(0)) == checked_length(UInt(1):UInt(1):UInt(0)) == 0 + @test length(typemax(UInt):UInt(1):(typemax(UInt)-1)) == checked_length(typemax(UInt):UInt(1):(typemax(UInt)-1)) == 0 + @test length(typemax(UInt):UInt(2):(typemax(UInt)-1)) == checked_length(typemax(UInt):UInt(2):(typemax(UInt)-1)) == 0 + @test length((typemin(Int)+3):5:(typemin(Int)+1)) == checked_length((typemin(Int)+3):5:(typemin(Int)+1)) == 0 end + # issue #6364 @test length((1:64)*(pi/5)) == 64 @@ -966,7 +1006,8 @@ end (Int8,UInt8,Int16,UInt16,Int32,UInt32) : (Int8,UInt8,Int16,UInt16)) for T in smallint - @test length(typemin(T):typemax(T)) == 2^(8*sizeof(T)) + s = typemin(T):typemax(T) + @test length(s) == checked_length(s) == 2^(8*sizeof(T)) end end @@ -974,7 +1015,7 @@ end @test (0:1//2:2)[1:2:3] == 0:1//1:1 # issue #12278 -@test length(1:UInt(0)) == 0 +@test length(1:UInt(0)) == checked_length(1:UInt(0)) == 0 @testset "zip" begin i = 0 @@ -1047,17 +1088,14 @@ end @test reverse(LinRange{Int}(0,3,4)) === LinRange{Int}(3,0,4) @test reverse(LinRange{Float64}(0.,3.,4)) === LinRange{Float64}(3.,0.,4) end -@testset "Issue #11245" begin - io = IOBuffer() - show(io, range(1, stop=2, length=3)) - str = String(take!(io)) -# @test str == "range(1.0, stop=2.0, length=3)" - @test str == "1.0:0.5:2.0" -end + +# issue #11245 +@test repr(range(1, stop=2, length=3)) == "1.0:0.5:2.0" @testset "issue 10950" begin r = 1//2:3 @test length(r) == 3 + @test_throws MethodError checked_length(r) == 3 # this would work if checked_sub is defined on Rational i = 1 for x in r @test x == i//2 @@ -1268,19 +1306,22 @@ end end r = 1f8-10:1f8 - @test_broken argmin(f) == argmin(collect(r)) - @test_broken argmax(f) == argmax(collect(r)) + rv = collect(r) + @test argmin(r) == argmin(rv) == 1 + @test r[argmax(r)] == r[argmax(rv)] == 1f8 + @test argmax(r) == lastindex(r) + @test argmax(rv) != lastindex(r) end @testset "OneTo" begin let r = Base.OneTo(-5) @test isempty(r) - @test length(r) == 0 + @test length(r) == checked_length(r) == 0 @test size(r) == (0,) end let r = Base.OneTo(3) @test !isempty(r) - @test length(r) == 3 + @test length(r) == checked_length(r) == 3 @test size(r) == (3,) @test step(r) == 1 @test first(r) == 1 @@ -1377,7 +1418,7 @@ end @testset "issue #20520" begin r = range(1.3173739f0, stop=1.3173739f0, length=3) - @test length(r) == 3 + @test length(r) == checked_length(r) == 3 @test first(r) === 1.3173739f0 @test last(r) === 1.3173739f0 @test r[2] === 1.3173739f0 @@ -1401,7 +1442,7 @@ using .Main.Furlongs @testset "dimensional correctness" begin @test length(Vector(Furlong(2):Furlong(10))) == 9 - @test length(range(Furlong(2), length=9)) == 9 + @test length(range(Furlong(2), length=9)) == checked_length(range(Furlong(2), length=9)) == 9 @test Vector(Furlong(2):Furlong(1):Furlong(10)) == Vector(range(Furlong(2), step=Furlong(1), length=9)) == Furlong.(2:10) @test Vector(Furlong(1.0):Furlong(0.5):Furlong(10.0)) == Vector(Furlong(1):Furlong(0.5):Furlong(10)) == Furlong.(1:0.5:10) @@ -1496,15 +1537,18 @@ module NonStandardIntegerRangeTest using Test +using Base.Checked: checked_length +import Base.Checked: checked_add, checked_sub + struct Position <: Integer val::Int end -Position(x::Position) = x # to resolve ambiguity with boot.jl:728 +Position(x::Position) = x # to resolve ambiguity with boot.jl:770 struct Displacement <: Integer val::Int end -Displacement(x::Displacement) = x # to resolve ambiguity with boot.jl:728 +Displacement(x::Displacement) = x # to resolve ambiguity with boot.jl:770 Base.:-(x::Displacement) = Displacement(-x.val) Base.:-(x::Position, y::Position) = Displacement(x.val - y.val) @@ -1521,14 +1565,67 @@ Base.Unsigned(x::Displacement) = Unsigned(x.val) Base.rem(x::Displacement, y::Displacement) = Displacement(rem(x.val, y.val)) Base.div(x::Displacement, y::Displacement) = Displacement(div(x.val, y.val)) -# required for collect (summing lengths); alternatively, should unsafe_length return Int by default? +# required for collect (summing lengths); alternatively, should length return Int by default? Base.promote_rule(::Type{Displacement}, ::Type{Int}) = Int Base.convert(::Type{Int}, x::Displacement) = x.val +# Unsigned complement, for testing checked_length +struct UPosition <: Unsigned + val::UInt +end +UPosition(x::UPosition) = x # to resolve ambiguity with boot.jl:770 + +struct UDisplacement <: Unsigned + val::UInt +end +UDisplacement(x::UDisplacement) = x # to resolve ambiguity with boot.jl:770 + +Base.show(io::IO, x::Union{Position, UPosition, Displacement, UDisplacement}) = + # should use show if we were to do this properly (instead of just a test-helper) + print(io, typeof(x).name.name, "(", x.val, ")") + +Base.:-(x::UPosition, y::UPosition) = UDisplacement(x.val - y.val) +Base.:-(x::UPosition, y::UDisplacement) = UPosition(x.val - y.val) +Base.:+(x::UPosition, y::UDisplacement) = UPosition(x.val + y.val) +Base.:+(x::UDisplacement, y::Displacement) = UDisplacement(x.val + y.val) +Base.:+(x::UDisplacement, y::UDisplacement) = UDisplacement(x.val + y.val) +checked_sub(x::UPosition, y::UPosition) = UDisplacement(checked_sub(x.val, y.val)) +checked_sub(x::UPosition, y::UDisplacement) = UPosition(checked_sub(x.val, y.val)) +checked_sub(x::UDisplacement, y::UDisplacement) = UDisplacement(checked_sub(x.val, y.val)) +checked_add(x::UPosition, y::UDisplacement) = UPosition(checked_add(x.val, y.val)) +checked_add(x::UDisplacement, y::UDisplacement) = UDisplacement(checked_add(x.val, y.val)) +Base.:+(x::UPosition, y::Displacement) = UPosition(x.val + y.val) +Base.:(<=)(x::UPosition, y::UPosition) = x.val <= y.val +Base.:(<)(x::UPosition, y::UPosition) = x.val < y.val +Base.:(<)(x::UDisplacement, y::UDisplacement) = x.val < y.val + +# for StepRange computation: +Base.rem(x::UDisplacement, y::Displacement) = UDisplacement(rem(x.val, y.val)) +Base.div(x::UDisplacement, y::Displacement) = UDisplacement(div(x.val, y.val)) +Base.rem(x::UDisplacement, y::UDisplacement) = UDisplacement(rem(x.val, y.val)) +Base.div(x::UDisplacement, y::UDisplacement) = UDisplacement(div(x.val, y.val)) + +#Base.promote_rule(::Type{UDisplacement}, ::Type{Int}) = Int +#Base.convert(::Type{Int}, x::UDisplacement) = Int(x.val) + @testset "Ranges with nonstandard Integers" begin for (start, stop) in [(2, 4), (3, 3), (3, -2)] - @test collect(Position(start) : Position(stop)) == Position.(start : stop) - end + r = Position(start) : Position(stop) + @test length(r) === Displacement(stop >= start ? stop - start + 1 : 0) + start >= 0 && stop >= 0 && @test UDisplacement(length(r).val) === + checked_length(UPosition(start) : UPosition(stop)) === + checked_length(UPosition(start) : Displacement(1) : UPosition(stop)) === + checked_length(UPosition(start) : UDisplacement(1) : UPosition(stop)) + @test collect(r) == Position.(start : stop) + end + + @test length(UPosition(3):Displacement(7):UPosition(100)) === checked_length(UPosition(3):Displacement(7):UPosition(100)) === UDisplacement(14) + @test length(UPosition(100):Displacement(7):UPosition(3)) === checked_length(UPosition(100):Displacement(7):UPosition(3)) === UDisplacement(0) + @test length(UPosition(100):Displacement(-7):UPosition(3)) === checked_length(UPosition(100):Displacement(-7):UPosition(3)) === UDisplacement(14) + @test length(UPosition(3):Displacement(-7):UPosition(100)) === checked_length(UPosition(3):Displacement(-7):UPosition(100)) === UDisplacement(0) + @test_throws OverflowError checked_length(zero(UPosition):UPosition(typemax(UInt))) + @test_throws OverflowError checked_length(zero(UPosition):Displacement(1):UPosition(typemax(UInt))) + @test_throws OverflowError checked_length(UPosition(typemax(UInt)):Displacement(-1):zero(UPosition)) for start in [3, 0, -2] @test collect(Base.OneTo(Position(start))) == Position.(Base.OneTo(start)) @@ -1550,7 +1647,7 @@ end end # module NonStandardIntegerRangeTest @testset "Issue #26619" begin - @test length(UInt(100) : -1 : 1) === UInt(100) + @test length(UInt(100) : -1 : 1) == checked_length(UInt(100) : -1 : 1) === UInt(100) @test collect(UInt(5) : -1 : 3) == [UInt(5), UInt(4), UInt(3)] let r = UInt(5) : -2 : 2 diff --git a/test/testhelpers/Furlongs.jl b/test/testhelpers/Furlongs.jl index 73d23a39d2d7b..f3583a532215a 100644 --- a/test/testhelpers/Furlongs.jl +++ b/test/testhelpers/Furlongs.jl @@ -20,7 +20,7 @@ Furlong{p}(x::Furlong{q}) where {p,q} = (@assert(p==q); Furlong{p,typeof(x.val)} Furlong{p,T}(x::Furlong{q}) where {T,p,q} = (@assert(p==q); Furlong{p,T}(T(x.val))) Base.promote_type(::Type{Furlong{p,T}}, ::Type{Furlong{p,S}}) where {p,T,S} = - (Base.@_pure_meta; Furlong{p,promote_type(T,S)}) + Furlong{p,promote_type(T,S)} Base.one(x::Furlong{p,T}) where {p,T} = one(T) Base.one(::Type{Furlong{p,T}}) where {p,T} = one(T) @@ -38,14 +38,12 @@ Base.floatmax(::Type{Furlong{p,T}}) where {p,T<:AbstractFloat} = Furlong{p}(floa Base.floatmax(::Furlong{p,T}) where {p,T<:AbstractFloat} = floatmax(Furlong{p,T}) Base.conj(x::Furlong{p,T}) where {p,T} = Furlong{p,T}(conj(x.val)) -# convert Furlong exponent p to a canonical form. This -# is not type stable, but it doesn't matter since it is used -# at compile time (in generated functions), not runtime +# convert Furlong exponent p to a canonical form canonical_p(p) = isinteger(p) ? Int(p) : Rational{Int}(p) Base.abs(x::Furlong{p}) where {p} = Furlong{p}(abs(x.val)) -@generated Base.abs2(x::Furlong{p}) where {p} = :(Furlong{$(canonical_p(2p))}(abs2(x.val))) -@generated Base.inv(x::Furlong{p}) where {p} = :(Furlong{$(canonical_p(-p))}(inv(x.val))) +Base.abs2(x::Furlong{p}) where {p} = Furlong{canonical_p(2p)}(abs2(x.val)) +Base.inv(x::Furlong{p}) where {p} = Furlong{canonical_p(-p)}(inv(x.val)) for f in (:isfinite, :isnan, :isreal, :isinf) @eval Base.$f(x::Furlong) = $f(x.val) @@ -64,11 +62,10 @@ end for op in (:(==), :(!=), :<, :<=, :isless, :isequal) @eval $op(x::Furlong{p}, y::Furlong{p}) where {p} = $op(x.val, y.val) end -# generated functions to allow type inference of the value of the exponent: for (f,op) in ((:_plus,:+),(:_minus,:-),(:_times,:*),(:_div,://)) - @eval @generated function $f(v::T, ::Furlong{p}, ::Union{Furlong{q},Val{q}}) where {T,p,q} + @eval function $f(v::T, ::Furlong{p}, ::Union{Furlong{q},Val{q}}) where {T,p,q} s = $op(p, q) - :(Furlong{$(canonical_p(s)),$T}(v)) + Furlong{canonical_p(s),T}(v) end end for (op,eop) in ((:*, :_plus), (:/, :_minus), (://, :_minus), (:div, :_minus)) diff --git a/test/testhelpers/InfiniteArrays.jl b/test/testhelpers/InfiniteArrays.jl index bc6de1afc5503..d69130f4d726a 100644 --- a/test/testhelpers/InfiniteArrays.jl +++ b/test/testhelpers/InfiniteArrays.jl @@ -39,13 +39,11 @@ struct OneToInf{T<:Integer} <: AbstractUnitRange{T} end OneToInf() = OneToInf{Int}() Base.axes(r::OneToInf) = (r,) -Base.unsafe_indices(r::OneToInf) = (r,) -Base.unsafe_length(r::OneToInf) = Infinity() Base.size(r::OneToInf) = (Infinity(),) Base.first(r::OneToInf{T}) where {T} = oneunit(T) -Base.length(r::OneToInf{T}) where {T} = Infinity() -Base.last(r::OneToInf{T}) where {T} = Infinity() +Base.length(r::OneToInf) = Infinity() +Base.last(r::OneToInf) = Infinity() Base.unitrange(r::OneToInf) = r Base.oneto(::Infinity) = OneToInf() -end \ No newline at end of file +end diff --git a/test/testhelpers/OffsetArrays.jl b/test/testhelpers/OffsetArrays.jl index 67de3ef476652..2f650808a12f2 100644 --- a/test/testhelpers/OffsetArrays.jl +++ b/test/testhelpers/OffsetArrays.jl @@ -68,7 +68,6 @@ offset_coerce(::Type{I}, r::AbstractUnitRange) where I<:AbstractUnitRange{T} whe @inline Base.parent(r::IdOffsetRange) = r.parent @inline Base.axes(r::IdOffsetRange) = (Base.axes1(r),) @inline Base.axes1(r::IdOffsetRange) = IdOffsetRange(Base.axes1(r.parent), r.offset) -@inline Base.unsafe_indices(r::IdOffsetRange) = (r,) @inline Base.length(r::IdOffsetRange) = length(r.parent) Base.reduced_index(i::IdOffsetRange) = typeof(i)(first(i):first(i)) # Workaround for #92 on Julia < 1.4 From be7ecbe9cf839d74057069d4677234e0f0c26867 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Fri, 23 Jul 2021 16:55:37 -0400 Subject: [PATCH 65/74] add length type parameter to StepRangeLen and LinRange (#41619) Allows creating these ranges for any type of integer lengths. Also need to be careful about using additive identity instead of multiplicative, and be even more consistent now about types in a few places. Fixes #41517 (cherry picked from commit 4f77aba13e5a6df1a8d255bbce472ac6934305c1) --- base/broadcast.jl | 21 +++-- base/range.jl | 193 +++++++++++++++++++++++------------------ base/twiceprecision.jl | 160 +++++++++++++++++++--------------- test/ranges.jl | 13 ++- 4 files changed, 223 insertions(+), 164 deletions(-) diff --git a/base/broadcast.jl b/base/broadcast.jl index c6651e28489a3..b34a73041708b 100644 --- a/base/broadcast.jl +++ b/base/broadcast.jl @@ -1121,19 +1121,20 @@ end ## scalar-range broadcast operations ## # DefaultArrayStyle and \ are not available at the time of range.jl -broadcasted(::DefaultArrayStyle{1}, ::typeof(+), r::OrdinalRange) = r -broadcasted(::DefaultArrayStyle{1}, ::typeof(+), r::StepRangeLen) = r -broadcasted(::DefaultArrayStyle{1}, ::typeof(+), r::LinRange) = r +broadcasted(::DefaultArrayStyle{1}, ::typeof(+), r::AbstractRange) = r -broadcasted(::DefaultArrayStyle{1}, ::typeof(-), r::OrdinalRange) = range(-first(r), step=-step(r), length=length(r)) +broadcasted(::DefaultArrayStyle{1}, ::typeof(-), r::AbstractRange) = range(-first(r), step=-step(r), length=length(r)) +broadcasted(::DefaultArrayStyle{1}, ::typeof(-), r::OrdinalRange) = range(-first(r), -last(r), step=-step(r)) broadcasted(::DefaultArrayStyle{1}, ::typeof(-), r::StepRangeLen) = StepRangeLen(-r.ref, -r.step, length(r), r.offset) broadcasted(::DefaultArrayStyle{1}, ::typeof(-), r::LinRange) = LinRange(-r.start, -r.stop, length(r)) -broadcasted(::DefaultArrayStyle{1}, ::typeof(+), x::Real, r::AbstractUnitRange) = range(x + first(r), length=length(r)) -broadcasted(::DefaultArrayStyle{1}, ::typeof(+), r::AbstractUnitRange, x::Real) = range(first(r) + x, length=length(r)) # For #18336 we need to prevent promotion of the step type: broadcasted(::DefaultArrayStyle{1}, ::typeof(+), r::AbstractRange, x::Number) = range(first(r) + x, step=step(r), length=length(r)) broadcasted(::DefaultArrayStyle{1}, ::typeof(+), x::Number, r::AbstractRange) = range(x + first(r), step=step(r), length=length(r)) +broadcasted(::DefaultArrayStyle{1}, ::typeof(+), r::OrdinalRange, x::Real) = range(first(r) + x, last(r) + x, step=step(r)) +broadcasted(::DefaultArrayStyle{1}, ::typeof(+), x::Real, r::Real) = range(x + first(r), x + last(r), step=step(r)) +broadcasted(::DefaultArrayStyle{1}, ::typeof(+), r::AbstractUnitRange, x::Real) = range(first(r) + x, last(r) + x) +broadcasted(::DefaultArrayStyle{1}, ::typeof(+), x::Real, r::AbstractUnitRange) = range(x + first(r), x + last(r)) broadcasted(::DefaultArrayStyle{1}, ::typeof(+), r::StepRangeLen{T}, x::Number) where T = StepRangeLen{typeof(T(r.ref)+x)}(r.ref + x, r.step, length(r), r.offset) broadcasted(::DefaultArrayStyle{1}, ::typeof(+), x::Number, r::StepRangeLen{T}) where T = @@ -1142,9 +1143,11 @@ broadcasted(::DefaultArrayStyle{1}, ::typeof(+), r::LinRange, x::Number) = LinRa broadcasted(::DefaultArrayStyle{1}, ::typeof(+), x::Number, r::LinRange) = LinRange(x + r.start, x + r.stop, length(r)) broadcasted(::DefaultArrayStyle{1}, ::typeof(+), r1::AbstractRange, r2::AbstractRange) = r1 + r2 -broadcasted(::DefaultArrayStyle{1}, ::typeof(-), r::AbstractUnitRange, x::Number) = range(first(r)-x, length=length(r)) -broadcasted(::DefaultArrayStyle{1}, ::typeof(-), r::AbstractRange, x::Number) = range(first(r)-x, step=step(r), length=length(r)) -broadcasted(::DefaultArrayStyle{1}, ::typeof(-), x::Number, r::AbstractRange) = range(x-first(r), step=-step(r), length=length(r)) +broadcasted(::DefaultArrayStyle{1}, ::typeof(-), r::AbstractRange, x::Number) = range(first(r) - x, step=step(r), length=length(r)) +broadcasted(::DefaultArrayStyle{1}, ::typeof(-), x::Number, r::AbstractRange) = range(x - first(r), step=-step(r), length=length(r)) +broadcasted(::DefaultArrayStyle{1}, ::typeof(-), r::OrdinalRange, x::Real) = range(first(r) - x, last(r) - x, step=step(r)) +broadcasted(::DefaultArrayStyle{1}, ::typeof(-), x::Real, r::OrdinalRange) = range(x - first(r), x - last(r), step=-step(r)) +broadcasted(::DefaultArrayStyle{1}, ::typeof(-), r::AbstractUnitRange, x::Real) = range(first(r) - x, last(r) - x) broadcasted(::DefaultArrayStyle{1}, ::typeof(-), r::StepRangeLen{T}, x::Number) where T = StepRangeLen{typeof(T(r.ref)-x)}(r.ref - x, r.step, length(r), r.offset) broadcasted(::DefaultArrayStyle{1}, ::typeof(-), x::Number, r::StepRangeLen{T}) where T = diff --git a/base/range.jl b/base/range.jl index e6a53e30892f3..9a7c74e4d4088 100644 --- a/base/range.jl +++ b/base/range.jl @@ -24,9 +24,9 @@ _colon(::Ordered, ::Any, start::T, step, stop::T) where {T} = StepRange(start, step, stop) # for T<:Union{Float16,Float32,Float64} see twiceprecision.jl _colon(::Ordered, ::ArithmeticRounds, start::T, step, stop::T) where {T} = - StepRangeLen(start, step, floor(Int, (stop-start)/step)+1) + StepRangeLen(start, step, floor(Integer, (stop-start)/step)+1) _colon(::Any, ::Any, start::T, step, stop::T) where {T} = - StepRangeLen(start, step, floor(Int, (stop-start)/step)+1) + StepRangeLen(start, step, floor(Integer, (stop-start)/step)+1) """ (:)(start, [step], stop) @@ -415,10 +415,11 @@ oneto(r) = OneTo(r) ## Step ranges parameterized by length """ - StepRangeLen{T,R,S}(ref::R, step::S, len, [offset=1]) where {T,R,S} - StepRangeLen( ref::R, step::S, len, [offset=1]) where { R,S} + StepRangeLen( ref::R, step::S, len, [offset=1]) where { R,S} + StepRangeLen{T,R,S}( ref::R, step::S, len, [offset=1]) where {T,R,S} + StepRangeLen{T,R,S,L}(ref::R, step::S, len, [offset=1]) where {T,R,S,L} -A range `r` where `r[i]` produces values of type `T` (in the second +A range `r` where `r[i]` produces values of type `T` (in the first form, `T` is deduced automatically), parameterized by a `ref`erence value, a `step`, and the `len`gth. By default `ref` is the starting value `r[1]`, but alternatively you can supply it as the value of @@ -426,40 +427,45 @@ value `r[1]`, but alternatively you can supply it as the value of with `TwicePrecision` this can be used to implement ranges that are free of roundoff error. """ -struct StepRangeLen{T,R,S} <: AbstractRange{T} +struct StepRangeLen{T,R,S,L<:Integer} <: AbstractRange{T} ref::R # reference value (might be smallest-magnitude value in the range) step::S # step value - len::Int # length of the range - offset::Int # the index of ref + len::L # length of the range + offset::L # the index of ref - function StepRangeLen{T,R,S}(ref::R, step::S, len::Integer, offset::Integer = 1) where {T,R,S} + function StepRangeLen{T,R,S,L}(ref::R, step::S, len::Integer, offset::Integer = 1) where {T,R,S,L} if T <: Integer && !isinteger(ref + step) throw(ArgumentError("StepRangeLen{<:Integer} cannot have non-integer step")) end - len >= 0 || throw(ArgumentError("length cannot be negative, got $len")) - 1 <= offset <= max(1,len) || throw(ArgumentError("StepRangeLen: offset must be in [1,$len], got $offset")) - new(ref, step, len, offset) + len = convert(L, len) + len >= zero(len) || throw(ArgumentError("length cannot be negative, got $len")) + offset = convert(L, offset) + L1 = oneunit(typeof(len)) + L1 <= offset <= max(L1, len) || throw(ArgumentError("StepRangeLen: offset must be in [1,$len], got $offset")) + return new(ref, step, len, offset) end end +StepRangeLen{T,R,S}(ref::R, step::S, len::Integer, offset::Integer = 1) where {T,R,S} = + StepRangeLen{T,R,S,promote_type(Int,typeof(len))}(ref, step, len, offset) StepRangeLen(ref::R, step::S, len::Integer, offset::Integer = 1) where {R,S} = - StepRangeLen{typeof(ref+zero(step)),R,S}(ref, step, len, offset) + StepRangeLen{typeof(ref+zero(step)),R,S,promote_type(Int,typeof(len))}(ref, step, len, offset) StepRangeLen{T}(ref::R, step::S, len::Integer, offset::Integer = 1) where {T,R,S} = - StepRangeLen{T,R,S}(ref, step, len, offset) + StepRangeLen{T,R,S,promote_type(Int,typeof(len))}(ref, step, len, offset) ## range with computed step """ - LinRange{T} + LinRange{T,L} A range with `len` linearly spaced elements between its `start` and `stop`. The size of the spacing is controlled by `len`, which must -be an `Int`. +be an `Integer`. # Examples ```jldoctest julia> LinRange(1.5, 5.5, 9) -9-element LinRange{Float64}: +9-element LinRange{Float64, Int64}: 1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,5.5 ``` @@ -483,26 +489,35 @@ julia> collect(LinRange(-0.1, 0.3, 5)) 0.3 ``` """ -struct LinRange{T} <: AbstractRange{T} +struct LinRange{T,L<:Integer} <: AbstractRange{T} start::T stop::T - len::Int - lendiv::Int + len::L + lendiv::L - function LinRange{T}(start,stop,len) where T + function LinRange{T,L}(start::T, stop::T, len::L) where {T,L<:Integer} len >= 0 || throw(ArgumentError("range($start, stop=$stop, length=$len): negative length")) - if len == 1 + onelen = oneunit(typeof(len)) + if len == onelen start == stop || throw(ArgumentError("range($start, stop=$stop, length=$len): endpoints differ")) - return new(start, stop, 1, 1) + return new(start, stop, len, len) end - lendiv = max(len-1, 1) + lendiv = max(len - onelen, onelen) if T <: Integer && !iszero(mod(stop-start, lendiv)) throw(ArgumentError("LinRange{<:Integer} cannot have non-integer step")) end - new(start,stop,len,lendiv) + return new(start, stop, len, lendiv) end end +function LinRange{T,L}(start, stop, len::Integer) where {T,L} + LinRange{T,L}(convert(T, start), convert(T, stop), convert(L, len)) +end + +function LinRange{T}(start, stop, len::Integer) where T + LinRange{T,promote_type(Int,typeof(len))}(start, stop, len) +end + function LinRange(start, stop, len::Integer) T = typeof((stop-start)/len) LinRange{T}(start, stop, len) @@ -621,6 +636,7 @@ step(r::StepRangeLen) = r.step step(r::StepRangeLen{T}) where {T<:AbstractFloat} = T(r.step) step(r::LinRange) = (last(r)-first(r))/r.lendiv +# high-precision step step_hp(r::StepRangeLen) = r.step step_hp(r::AbstractRange) = step(r) @@ -648,7 +664,7 @@ function checked_length(r::OrdinalRange{T}) where T diff = checked_sub(stop, start) end a = Integer(div(diff, s)) - return checked_add(a, one(a)) + return checked_add(a, oneunit(a)) end function checked_length(r::AbstractUnitRange{T}) where T @@ -657,7 +673,7 @@ function checked_length(r::AbstractUnitRange{T}) where T return Integer(first(r) - first(r)) end a = Integer(checked_add(checked_sub(last(r), first(r)))) - return checked_add(a, one(a)) + return checked_add(a, oneunit(a)) end function length(r::OrdinalRange{T}) where T @@ -675,14 +691,14 @@ function length(r::OrdinalRange{T}) where T diff = stop - start end a = Integer(div(diff, s)) - return a + one(a) + return a + oneunit(a) end function length(r::AbstractUnitRange{T}) where T @_inline_meta a = Integer(last(r) - first(r)) # even when isempty, by construction (with overflow) - return a + one(a) + return a + oneunit(a) end length(r::OneTo) = Integer(r.stop - zero(r.stop)) @@ -710,7 +726,7 @@ let bigints = Union{Int, UInt, Int64, UInt64, Int128, UInt128} else a = div(unsigned(diff), s) % typeof(diff) end - return Integer(a) + one(a) + return Integer(a) + oneunit(a) end function checked_length(r::OrdinalRange{T}) where T<:bigints s = step(r) @@ -729,7 +745,7 @@ let bigints = Union{Int, UInt, Int64, UInt64, Int128, UInt128} else a = div(checked_sub(start, stop), -s) end - return checked_add(a, one(a)) + return checked_add(a, oneunit(a)) end end @@ -803,10 +819,11 @@ copy(r::AbstractRange) = r ## iteration -function iterate(r::Union{LinRange,StepRangeLen}, i::Int=1) +function iterate(r::Union{StepRangeLen,LinRange}, i::Integer=zero(length(r))) @_inline_meta + i += oneunit(i) length(r) < i && return nothing - unsafe_getindex(r, i), i + 1 + unsafe_getindex(r, i), i end iterate(r::OrdinalRange) = isempty(r) ? nothing : (first(r), first(r)) @@ -897,7 +914,7 @@ function getindex(r::AbstractUnitRange, s::AbstractUnitRange{T}) where {T<:Integ @boundscheck checkbounds(r, s) if T === Bool - range(first(s) ? first(r) : last(r), length = Int(last(s))) + range(first(s) ? first(r) : last(r), length = Integer(last(s))) else f = first(r) st = oftype(f, f + first(s)-1) @@ -916,7 +933,7 @@ function getindex(r::AbstractUnitRange, s::StepRange{T}) where {T<:Integer} @boundscheck checkbounds(r, s) if T === Bool - range(first(s) ? first(r) : last(r), step=oneunit(eltype(r)), length = Int(last(s))) + range(first(s) ? first(r) : last(r), step=oneunit(eltype(r)), length = Integer(last(s))) else st = oftype(first(r), first(r) + s.start-1) return range(st, step=step(s), length=length(s)) @@ -949,24 +966,29 @@ function getindex(r::StepRangeLen{T}, s::OrdinalRange{S}) where {T, S<:Integer} @_inline_meta @boundscheck checkbounds(r, s) + len = length(s) + sstep = step_hp(s) + rstep = step_hp(r) + L = typeof(len) if S === Bool - if length(s) == 0 - return StepRangeLen{T}(first(r), step(r), 0, 1) - elseif length(s) == 1 + rstep *= one(sstep) + if len == 0 + return StepRangeLen{T}(first(r), rstep, zero(L), oneunit(L)) + elseif len == 1 if first(s) - return StepRangeLen{T}(first(r), step(r), 1, 1) + return StepRangeLen{T}(first(r), rstep, oneunit(L), oneunit(L)) else - return StepRangeLen{T}(first(r), step(r), 0, 1) + return StepRangeLen{T}(first(r), rstep, zero(L), oneunit(L)) end - else # length(s) == 2 - return StepRangeLen{T}(last(r), step(r), 1, 1) + else # len == 2 + return StepRangeLen{T}(last(r), rstep, oneunit(L), oneunit(L)) end else # Find closest approach to offset by s ind = LinearIndices(s) - offset = max(min(1 + round(Int, (r.offset - first(s))/step(s)), last(ind)), first(ind)) - ref = _getindex_hiprec(r, first(s) + (offset-1)*step(s)) - return StepRangeLen{T}(ref, r.step*step(s), length(s), offset) + offset = L(max(min(1 + round(L, (r.offset - first(s))/sstep), last(ind)), first(ind))) + ref = _getindex_hiprec(r, first(s) + (offset-1)*sstep) + return StepRangeLen{T}(ref, rstep*sstep, len, offset) end end @@ -974,22 +996,24 @@ function getindex(r::LinRange{T}, s::OrdinalRange{S}) where {T, S<:Integer} @_inline_meta @boundscheck checkbounds(r, s) + len = length(s) + L = typeof(len) if S === Bool - if length(s) == 0 - return LinRange(first(r), first(r), 0) - elseif length(s) == 1 + if len == 0 + return LinRange{T}(first(r), first(r), len) + elseif len == 1 if first(s) - return LinRange(first(r), first(r), 1) + return LinRange{T}(first(r), first(r), len) else - return LinRange(first(r), first(r), 0) + return LinRange{T}(first(r), first(r), zero(L)) end else # length(s) == 2 - return LinRange(last(r), last(r), 1) + return LinRange{T}(last(r), last(r), oneunit(L)) end else vfirst = unsafe_getindex(r, first(s)) vlast = unsafe_getindex(r, last(s)) - return LinRange{T}(vfirst, vlast, length(s)) + return LinRange{T}(vfirst, vlast, len) end end @@ -1153,8 +1177,8 @@ issubset(r::AbstractUnitRange{<:Integer}, s::AbstractUnitRange{<:Integer}) = ## linear operations on ranges ## -(r::OrdinalRange) = range(-first(r), step=-step(r), length=length(r)) --(r::StepRangeLen{T,R,S}) where {T,R,S} = - StepRangeLen{T,R,S}(-r.ref, -r.step, length(r), r.offset) +-(r::StepRangeLen{T,R,S,L}) where {T,R,S,L} = + StepRangeLen{T,R,S,L}(-r.ref, -r.step, r.len, r.offset) function -(r::LinRange) start = -r.start LinRange{typeof(start)}(start, -r.stop, length(r)) @@ -1168,12 +1192,12 @@ el_same(::Type{T}, a::Type{<:AbstractArray{S,n}}, b::Type{<:AbstractArray{T,n}}) el_same(::Type, a, b) = promote_typejoin(a, b) promote_rule(a::Type{UnitRange{T1}}, b::Type{UnitRange{T2}}) where {T1,T2} = - el_same(promote_type(T1,T2), a, b) + el_same(promote_type(T1, T2), a, b) UnitRange{T}(r::UnitRange{T}) where {T<:Real} = r UnitRange{T}(r::UnitRange) where {T<:Real} = UnitRange{T}(r.start, r.stop) promote_rule(a::Type{OneTo{T1}}, b::Type{OneTo{T2}}) where {T1,T2} = - el_same(promote_type(T1,T2), a, b) + el_same(promote_type(T1, T2), a, b) OneTo{T}(r::OneTo{T}) where {T<:Integer} = r OneTo{T}(r::OneTo) where {T<:Integer} = OneTo{T}(r.stop) @@ -1191,11 +1215,11 @@ OrdinalRange{T1, T2}(r::AbstractUnitRange{T1}) where {T1, T2<:Integer} = r OrdinalRange{T1, T2}(r::UnitRange) where {T1, T2<:Integer} = UnitRange{T1}(r) OrdinalRange{T1, T2}(r::OneTo) where {T1, T2<:Integer} = OneTo{T1}(r) -promote_rule(::Type{StepRange{T1a,T1b}}, ::Type{StepRange{T2a,T2b}}) where {T1a,T1b,T2a,T2b} = - el_same(promote_type(T1a,T2a), - # el_same only operates on array element type, so just promote second type parameter - StepRange{T1a, promote_type(T1b,T2b)}, - StepRange{T2a, promote_type(T1b,T2b)}) +function promote_rule(::Type{StepRange{T1a,T1b}}, ::Type{StepRange{T2a,T2b}}) where {T1a,T1b,T2a,T2b} + Tb = promote_type(T1b, T2b) + # el_same only operates on array element type, so just promote second type parameter + el_same(promote_type(T1a, T2a), StepRange{T1a,Tb}, StepRange{T2a,Tb}) +end StepRange{T1,T2}(r::StepRange{T1,T2}) where {T1,T2} = r promote_rule(a::Type{StepRange{T1a,T1b}}, ::Type{UR}) where {T1a,T1b,UR<:AbstractUnitRange} = @@ -1206,35 +1230,38 @@ StepRange(r::AbstractUnitRange{T}) where {T} = StepRange{T,T}(first(r), step(r), last(r)) (StepRange{T1,T2} where T1)(r::AbstractRange) where {T2} = StepRange{eltype(r),T2}(r) -promote_rule(::Type{StepRangeLen{T1,R1,S1}},::Type{StepRangeLen{T2,R2,S2}}) where {T1,T2,R1,R2,S1,S2} = - el_same(promote_type(T1,T2), - StepRangeLen{T1,promote_type(R1,R2),promote_type(S1,S2)}, - StepRangeLen{T2,promote_type(R1,R2),promote_type(S1,S2)}) -StepRangeLen{T,R,S}(r::StepRangeLen{T,R,S}) where {T,R,S} = r -StepRangeLen{T,R,S}(r::StepRangeLen) where {T,R,S} = - StepRangeLen{T,R,S}(convert(R, r.ref), convert(S, r.step), length(r), r.offset) +function promote_rule(::Type{StepRangeLen{T1,R1,S1,L1}},::Type{StepRangeLen{T2,R2,S2,L2}}) where {T1,T2,R1,R2,S1,S2,L1,L2} + R, S, L = promote_type(R1, R2), promote_type(S1, S2), promote_type(L1, L2) + el_same(promote_type(T1, T2), StepRangeLen{T1,R,S,L}, StepRangeLen{T2,R,S,L}) +end +StepRangeLen{T,R,S,L}(r::StepRangeLen{T,R,S,L}) where {T,R,S,L} = r +StepRangeLen{T,R,S,L}(r::StepRangeLen) where {T,R,S,L} = + StepRangeLen{T,R,S,L}(convert(R, r.ref), convert(S, r.step), convert(L, r.len), convert(L, r.offset)) StepRangeLen{T}(r::StepRangeLen) where {T} = - StepRangeLen(convert(T, r.ref), convert(T, r.step), length(r), r.offset) + StepRangeLen(convert(T, r.ref), convert(T, r.step), r.len, r.offset) -promote_rule(a::Type{StepRangeLen{T,R,S}}, ::Type{OR}) where {T,R,S,OR<:AbstractRange} = - promote_rule(a, StepRangeLen{eltype(OR), eltype(OR), eltype(OR)}) -StepRangeLen{T,R,S}(r::AbstractRange) where {T,R,S} = - StepRangeLen{T,R,S}(R(first(r)), S(step(r)), length(r)) +promote_rule(a::Type{StepRangeLen{T,R,S,L}}, ::Type{OR}) where {T,R,S,L,OR<:AbstractRange} = + promote_rule(a, StepRangeLen{eltype(OR), eltype(OR), eltype(OR), Int}) +StepRangeLen{T,R,S,L}(r::AbstractRange) where {T,R,S,L} = + StepRangeLen{T,R,S,L}(R(first(r)), S(step(r)), length(r)) StepRangeLen{T}(r::AbstractRange) where {T} = StepRangeLen(T(first(r)), T(step(r)), length(r)) StepRangeLen(r::AbstractRange) = StepRangeLen{eltype(r)}(r) -promote_rule(a::Type{LinRange{T1}}, b::Type{LinRange{T2}}) where {T1,T2} = - el_same(promote_type(T1,T2), a, b) -LinRange{T}(r::LinRange{T}) where {T} = r -LinRange{T}(r::AbstractRange) where {T} = LinRange{T}(first(r), last(r), length(r)) +function promote_rule(a::Type{LinRange{T1,L1}}, b::Type{LinRange{T2,L2}}) where {T1,T2,L1,L2} + L = promote_type(L1, L2) + el_same(promote_type(T1, T2), LinRange{T1,L}, LinRange{T2,L}) +end +LinRange{T,L}(r::LinRange{T,L}) where {T,L} = r +LinRange{T,L}(r::AbstractRange) where {T,L} = LinRange{T,L}(first(r), last(r), length(r)) +LinRange{T}(r::AbstractRange) where {T} = LinRange{T,typeof(length(r))}(first(r), last(r), length(r)) LinRange(r::AbstractRange{T}) where {T} = LinRange{T}(r) -promote_rule(a::Type{LinRange{T}}, ::Type{OR}) where {T,OR<:OrdinalRange} = - promote_rule(a, LinRange{eltype(OR)}) +promote_rule(a::Type{LinRange{T,L}}, ::Type{OR}) where {T,L,OR<:OrdinalRange} = + promote_rule(a, LinRange{eltype(OR),L}) -promote_rule(::Type{LinRange{L}}, b::Type{StepRangeLen{T,R,S}}) where {L,T,R,S} = - promote_rule(StepRangeLen{L,L,L}, b) +promote_rule(::Type{LinRange{A,L}}, b::Type{StepRangeLen{T2,R2,S2,L2}}) where {A,L,T2,R2,S2,L2} = + promote_rule(StepRangeLen{A,A,A,L}, b) ## concatenation ## @@ -1261,9 +1288,9 @@ function _reverse(r::StepRangeLen, ::Colon) # invalid. As `reverse(r)` is also empty, any offset would work so we keep # `r.offset` offset = isempty(r) ? r.offset : length(r)-r.offset+1 - StepRangeLen(r.ref, -r.step, length(r), offset) + return typeof(r)(r.ref, -r.step, length(r), offset) end -_reverse(r::LinRange{T}, ::Colon) where {T} = LinRange{T}(r.stop, r.start, length(r)) +_reverse(r::LinRange{T}, ::Colon) where {T} = typeof(r)(r.stop, r.start, length(r)) ## sorting ## diff --git a/base/twiceprecision.jl b/base/twiceprecision.jl index 55cdc59371674..a7ff116b56b36 100644 --- a/base/twiceprecision.jl +++ b/base/twiceprecision.jl @@ -194,6 +194,10 @@ function TwicePrecision{T}(x) where {T} TwicePrecision{T}(xT, T(Δx)) end +function TwicePrecision{T}(x::TwicePrecision) where {T} + TwicePrecision{T}(x.hi, x.lo) +end + TwicePrecision{T}(i::Integer) where {T<:AbstractFloat} = TwicePrecision{T}(canonicalize2(splitprec(T, i)...)...) @@ -207,7 +211,7 @@ end function TwicePrecision{T}(nd::Tuple{Any,Any}) where {T} n, d = nd - TwicePrecision{T}(n) / d + TwicePrecision{T}(TwicePrecision{T}(n) / d) end function TwicePrecision{T}(nd::Tuple{I,I}, nb::Integer) where {T,I} @@ -329,13 +333,13 @@ function steprangelen_hp(::Type{Float64}, ref::Tuple{Integer,Integer}, step::Tuple{Integer,Integer}, nb::Integer, len::Integer, offset::Integer) StepRangeLen(TwicePrecision{Float64}(ref), - TwicePrecision{Float64}(step, nb), Int(len), offset) + TwicePrecision{Float64}(step, nb), len, offset) end function steprangelen_hp(::Type{T}, ref::Tuple{Integer,Integer}, step::Tuple{Integer,Integer}, nb::Integer, len::Integer, offset::Integer) where {T<:IEEEFloat} - StepRangeLen{T}(ref[1]/ref[2], step[1]/step[2], Int(len), offset) + StepRangeLen{T}(ref[1]/ref[2], step[1]/step[2], len, offset) end # AbstractFloat constructors (can supply a single number or a 2-tuple @@ -347,14 +351,13 @@ function steprangelen_hp(::Type{Float64}, ref::F_or_FF, step::F_or_FF, nb::Integer, len::Integer, offset::Integer) StepRangeLen(TwicePrecision{Float64}(ref...), - twiceprecision(TwicePrecision{Float64}(step...), nb), Int(len), offset) + twiceprecision(TwicePrecision{Float64}(step...), nb), len, offset) end function steprangelen_hp(::Type{T}, ref::F_or_FF, step::F_or_FF, nb::Integer, len::Integer, offset::Integer) where {T<:IEEEFloat} - StepRangeLen{T}(asF64(ref), - asF64(step), Int(len), offset) + StepRangeLen{T}(asF64(ref), asF64(step), len, offset) end @@ -365,30 +368,33 @@ StepRangeLen(ref::TwicePrecision{T}, step::TwicePrecision{T}, # Construct range for rational start=start_n/den, step=step_n/den function floatrange(::Type{T}, start_n::Integer, step_n::Integer, len::Integer, den::Integer) where T + len = len + 0 # promote with Int if len < 2 || step_n == 0 - return steprangelen_hp(T, (start_n, den), (step_n, den), 0, Int(len), 1) + return steprangelen_hp(T, (start_n, den), (step_n, den), 0, len, oneunit(len)) end # index of smallest-magnitude value - imin = clamp(round(Int, -start_n/step_n+1), 1, Int(len)) + L = typeof(len) + imin = clamp(round(typeof(len), -start_n/step_n+1), oneunit(L), len) # Compute smallest-magnitude element to 2x precision ref_n = start_n+(imin-1)*step_n # this shouldn't overflow, so don't check nb = nbitslen(T, len, imin) - steprangelen_hp(T, (ref_n, den), (step_n, den), nb, Int(len), imin) + steprangelen_hp(T, (ref_n, den), (step_n, den), nb, len, imin) end function floatrange(a::AbstractFloat, st::AbstractFloat, len::Real, divisor::AbstractFloat) + len = len + 0 # promote with Int T = promote_type(typeof(a), typeof(st), typeof(divisor)) m = maxintfloat(T, Int) if abs(a) <= m && abs(st) <= m && abs(divisor) <= m ia, ist, idivisor = round(Int, a), round(Int, st), round(Int, divisor) if ia == a && ist == st && idivisor == divisor # We can return the high-precision range - return floatrange(T, ia, ist, Int(len), idivisor) + return floatrange(T, ia, ist, len, idivisor) end end # Fallback (misses the opportunity to set offset different from 1, # but otherwise this is still high-precision) - steprangelen_hp(T, (a,divisor), (st,divisor), nbitslen(T, len, 1), Int(len), 1) + steprangelen_hp(T, (a,divisor), (st,divisor), nbitslen(T, len, 1), len, oneunit(len)) end function (:)(start::T, step::T, stop::T) where T<:Union{Float16,Float32,Float64} @@ -407,7 +413,7 @@ function (:)(start::T, step::T, stop::T) where T<:Union{Float16,Float32,Float64} rem(den, start_d) == 0 && rem(den, step_d) == 0 # check lcm overflow start_n = round(Int, start*den) step_n = round(Int, step*den) - len = max(0, div(den*stop_n - stop_d*start_n + step_n*stop_d, step_n*stop_d)) + len = max(0, Int(div(den*stop_n - stop_d*start_n + step_n*stop_d, step_n*stop_d))) # Integer ops could overflow, so check that this makes sense if isbetween(start, start + (len-1)*step, stop + step/2) && !isbetween(start, start + len*step, stop) @@ -418,6 +424,7 @@ function (:)(start::T, step::T, stop::T) where T<:Union{Float16,Float32,Float64} end end # Fallback, taking start and step literally + # n.b. we use Int as the default length type for IEEEFloats lf = (stop-start)/step if lf < 0 len = 0 @@ -436,6 +443,7 @@ step(r::StepRangeLen{T,TwicePrecision{T},TwicePrecision{T}}) where {T<:AbstractF step(r::StepRangeLen{T,TwicePrecision{T},TwicePrecision{T}}) where {T} = T(r.step) function range_start_step_length(a::T, st::T, len::Integer) where T<:Union{Float16,Float32,Float64} + len = len + 0 # promote with Int start_n, start_d = rat(a) step_n, step_d = rat(st) if start_d != 0 && step_d != 0 && @@ -474,31 +482,38 @@ end function getindex(r::StepRangeLen{T,<:TwicePrecision,<:TwicePrecision}, s::OrdinalRange{S}) where {T, S<:Integer} @boundscheck checkbounds(r, s) + len = length(s) + L = typeof(len) + sstep = step_hp(s) + rstep = step_hp(r) if S === Bool - if length(s) == 0 - return StepRangeLen(r.ref, r.step, 0, 1) - elseif length(s) == 1 + #rstep *= one(sstep) + if len == 0 + return StepRangeLen{T}(first(r), rstep, zero(L), oneunit(L)) + elseif len == 1 if first(s) - return StepRangeLen(r.ref, r.step, 1, 1) + return StepRangeLen{T}(first(r), rstep, oneunit(L), oneunit(L)) else - return StepRangeLen(r.ref, r.step, 0, 1) + return StepRangeLen{T}(first(r), rstep, zero(L), oneunit(L)) end - else # length(s) == 2 - return StepRangeLen(r[2], step(r), 1, 1) + else # len == 2 + return StepRangeLen{T}(last(r), step(r), oneunit(L), oneunit(L)) end else - soffset = 1 + round(Int, (r.offset - first(s))/step(s)) - soffset = clamp(soffset, 1, length(s)) - ioffset = first(s) + (soffset-1)*step(s) - if step(s) == 1 || length(s) < 2 - newstep = r.step + soffset = round(L, (r.offset - first(s))/sstep + 1) + soffset = clamp(soffset, oneunit(L), len) + ioffset = L(first(s) + (soffset - oneunit(L)) * sstep) + if sstep == 1 || len < 2 + newstep = rstep #* one(sstep) else - newstep = twiceprecision(r.step*step(s), nbitslen(T, length(s), soffset)) + newstep = rstep * sstep + newstep = twiceprecision(newstep, nbitslen(T, len, soffset)) end + soffset = max(oneunit(L), soffset) if ioffset == r.offset - return StepRangeLen(r.ref, newstep, length(s), max(1,soffset)) + return StepRangeLen{T}(r.ref, newstep, len, soffset) else - return StepRangeLen(r.ref + (ioffset-r.offset)*r.step, newstep, length(s), max(1,soffset)) + return StepRangeLen{T}(r.ref + (ioffset-r.offset)*rstep, newstep, len, soffset) end end end @@ -509,30 +524,30 @@ end /(r::StepRangeLen{<:Real,<:TwicePrecision}, x::Real) = StepRangeLen(r.ref/x, twiceprecision(r.step/x, nbitslen(r)), length(r), r.offset) -StepRangeLen{T,R,S}(r::StepRangeLen{T,R,S}) where {T<:AbstractFloat,R<:TwicePrecision,S<:TwicePrecision} = r +StepRangeLen{T,R,S,L}(r::StepRangeLen{T,R,S,L}) where {T<:AbstractFloat,R<:TwicePrecision,S<:TwicePrecision,L} = r -StepRangeLen{T,R,S}(r::StepRangeLen) where {T<:AbstractFloat,R<:TwicePrecision,S<:TwicePrecision} = - _convertSRL(StepRangeLen{T,R,S}, r) +StepRangeLen{T,R,S,L}(r::StepRangeLen) where {T<:AbstractFloat,R<:TwicePrecision,S<:TwicePrecision,L} = + _convertSRL(StepRangeLen{T,R,S,L}, r) StepRangeLen{Float64}(r::StepRangeLen) = - _convertSRL(StepRangeLen{Float64,TwicePrecision{Float64},TwicePrecision{Float64}}, r) + _convertSRL(StepRangeLen{Float64,TwicePrecision{Float64},TwicePrecision{Float64},Int}, r) StepRangeLen{T}(r::StepRangeLen) where {T<:IEEEFloat} = - _convertSRL(StepRangeLen{T,Float64,Float64}, r) + _convertSRL(StepRangeLen{T,Float64,Float64,Int}, r) StepRangeLen{Float64}(r::AbstractRange) = - _convertSRL(StepRangeLen{Float64,TwicePrecision{Float64},TwicePrecision{Float64}}, r) + _convertSRL(StepRangeLen{Float64,TwicePrecision{Float64},TwicePrecision{Float64},Int}, r) StepRangeLen{T}(r::AbstractRange) where {T<:IEEEFloat} = - _convertSRL(StepRangeLen{T,Float64,Float64}, r) + _convertSRL(StepRangeLen{T,Float64,Float64,Int}, r) -function _convertSRL(::Type{StepRangeLen{T,R,S}}, r::StepRangeLen{<:Integer}) where {T,R,S} - StepRangeLen{T,R,S}(R(r.ref), S(r.step), length(r), r.offset) +function _convertSRL(::Type{StepRangeLen{T,R,S,L}}, r::StepRangeLen{<:Integer}) where {T,R,S,L} + StepRangeLen{T,R,S,L}(R(r.ref), S(r.step), L(length(r)), L(r.offset)) end -function _convertSRL(::Type{StepRangeLen{T,R,S}}, r::AbstractRange{<:Integer}) where {T,R,S} - StepRangeLen{T,R,S}(R(first(r)), S(step(r)), length(r)) +function _convertSRL(::Type{StepRangeLen{T,R,S,L}}, r::AbstractRange{<:Integer}) where {T,R,S,L} + StepRangeLen{T,R,S,L}(R(first(r)), S(step(r)), L(length(r))) end -function _convertSRL(::Type{StepRangeLen{T,R,S}}, r::AbstractRange{U}) where {T,R,S,U} +function _convertSRL(::Type{StepRangeLen{T,R,S,L}}, r::AbstractRange{U}) where {T,R,S,L,U} # if start and step have a rational approximation in the old type, # then we transfer that rational approximation to the new type f, s = first(r), step(r) @@ -546,17 +561,17 @@ function _convertSRL(::Type{StepRangeLen{T,R,S}}, r::AbstractRange{U}) where {T, rem(den, start_d) == 0 && rem(den, step_d) == 0 start_n = round(Int, f*den) step_n = round(Int, s*den) - return floatrange(T, start_n, step_n, length(r), den) + return floatrange(T, start_n, step_n, L(length(r)), den) end end - __convertSRL(StepRangeLen{T,R,S}, r) + return __convertSRL(StepRangeLen{T,R,S,L}, r) end -function __convertSRL(::Type{StepRangeLen{T,R,S}}, r::StepRangeLen{U}) where {T,R,S,U} - StepRangeLen{T,R,S}(R(r.ref), S(r.step), length(r), r.offset) +function __convertSRL(::Type{StepRangeLen{T,R,S,L}}, r::StepRangeLen{U}) where {T,R,S,L,U} + StepRangeLen{T,R,S,L}(R(r.ref), S(r.step), L(length(r)), L(r.offset)) end -function __convertSRL(::Type{StepRangeLen{T,R,S}}, r::AbstractRange{U}) where {T,R,S,U} - StepRangeLen{T,R,S}(R(first(r)), S(step(r)), length(r)) +function __convertSRL(::Type{StepRangeLen{T,R,S,L}}, r::AbstractRange{U}) where {T,R,S,L,U} + StepRangeLen{T,R,S,L}(R(first(r)), S(step(r)), L(length(r))) end function sum(r::StepRangeLen) @@ -567,7 +582,7 @@ function sum(r::StepRangeLen) np, nn = l - r.offset, r.offset - 1 # positive, negative # To prevent overflow in sum(1:n), multiply its factors by the step sp, sn = sumpair(np), sumpair(nn) - W = widen(Int) + W = widen(typeof(l)) Δn = W(sp[1]) * W(sp[2]) - W(sn[1]) * W(sn[2]) s = r.step * Δn # Add in contributions of ref @@ -603,19 +618,20 @@ function +(r1::StepRangeLen{T,R}, r2::StepRangeLen{T,R}) where T where R<:TwiceP imid = r1.offset ref = r1.ref + r2.ref else - imid = round(Int, (r1.offset+r2.offset)/2) + imid = round(typeof(len), (r1.offset+r2.offset)/2) ref1mid = _getindex_hiprec(r1, imid) ref2mid = _getindex_hiprec(r2, imid) ref = ref1mid + ref2mid end step = twiceprecision(r1.step + r2.step, nbitslen(T, len, imid)) - StepRangeLen{T,typeof(ref),typeof(step)}(ref, step, len, imid) + StepRangeLen{T,typeof(ref),typeof(step),typeof(len)}(ref, step, len, imid) end ## LinRange # For Float16, Float32, and Float64, this returns a StepRangeLen function range_start_stop_length(start::T, stop::T, len::Integer) where {T<:IEEEFloat} + len = len + 0 # promote with Int len < 2 && return _linspace1(T, start, stop, len) if start == stop return steprangelen_hp(T, start, zero(T), 0, len, 1) @@ -638,32 +654,35 @@ function range_start_stop_length(start::T, stop::T, len::Integer) where {T<:IEEE end function _linspace(start::T, stop::T, len::Integer) where {T<:IEEEFloat} + len = len + 0 # promote with Int (isfinite(start) && isfinite(stop)) || throw(ArgumentError("start and stop must be finite, got $start and $stop")) # Find the index that returns the smallest-magnitude element Δ, Δfac = stop-start, 1 if !isfinite(Δ) # handle overflow for large endpoints - Δ, Δfac = stop/len - start/len, Int(len) + Δ, Δfac = stop/len - start/len, len end tmin = -(start/Δ)/Δfac # t such that (1-t)*start + t*stop == 0 - imin = round(Int, tmin*(len-1)+1) # index approximately corresponding to t + L = typeof(len) + lenn1 = len - oneunit(L) + imin = round(L, tmin*lenn1 + 1) # index approximately corresponding to t if 1 < imin < len # The smallest-magnitude element is in the interior - t = (imin-1)/(len-1) + t = (imin - 1)/lenn1 ref = T((1-t)*start + t*stop) step = imin-1 < len-imin ? (ref-start)/(imin-1) : (stop-ref)/(len-imin) elseif imin <= 1 - imin = 1 + imin = oneunit(L) ref = start - step = (Δ/(len-1))*Δfac + step = (Δ/(lenn1))*Δfac else - imin = Int(len) + imin = len ref = stop - step = (Δ/(len-1))*Δfac + step = (Δ/(lenn1))*Δfac end if len == 2 && !isfinite(step) # For very large endpoints where step overflows, exploit the # split-representation to handle the overflow - return steprangelen_hp(T, start, (-start, stop), 0, 2, 1) + return steprangelen_hp(T, start, (-start, stop), 0, len, oneunit(L)) end # 2x calculations to get high precision endpoint matching while also # preventing overflow in ref_hi+(i-offset)*step_hi @@ -676,23 +695,28 @@ function _linspace(start::T, stop::T, len::Integer) where {T<:IEEEFloat} a, b = (start - x1_hi) - x1_lo, (stop - x2_hi) - x2_lo step_lo = (b - a)/(len - 1) ref_lo = a - (1 - imin)*step_lo - steprangelen_hp(T, (ref, ref_lo), (step_hi, step_lo), 0, Int(len), imin) + steprangelen_hp(T, (ref, ref_lo), (step_hi, step_lo), 0, len, imin) end # range for rational numbers, start = start_n/den, stop = stop_n/den # Note this returns a StepRangeLen _linspace(::Type{T}, start::Integer, stop::Integer, len::Integer) where {T<:IEEEFloat} = _linspace(T, start, stop, len, one(start)) function _linspace(::Type{T}, start_n::Integer, stop_n::Integer, len::Integer, den::Integer) where T<:IEEEFloat + len = len + 0 # promote with Int len < 2 && return _linspace1(T, start_n/den, stop_n/den, len) - start_n == stop_n && return steprangelen_hp(T, (start_n, den), (zero(start_n), den), 0, len, 1) + L = typeof(len) + start_n == stop_n && return steprangelen_hp(T, (start_n, den), (zero(start_n), den), 0, len, oneunit(L)) tmin = -start_n/(Float64(stop_n) - Float64(start_n)) - imin = round(Int, tmin*(len-1)+1) - imin = clamp(imin, 1, Int(len)) - ref_num = Int128(len-imin) * start_n + Int128(imin-1) * stop_n - ref_denom = Int128(len-1) * den + imin = round(typeof(len), tmin*(len-1)+1) + imin = clamp(imin, oneunit(L), len) + W = widen(L) + start_n = W(start_n) + stop_n = W(stop_n) + ref_num = W(len-imin) * start_n + W(imin-1) * stop_n + ref_denom = W(len-1) * den ref = (ref_num, ref_denom) - step_full = (Int128(stop_n) - Int128(start_n), ref_denom) - steprangelen_hp(T, ref, step_full, nbitslen(T, len, imin), Int(len), imin) + step_full = (stop_n - start_n, ref_denom) + steprangelen_hp(T, ref, step_full, nbitslen(T, len, imin), len, imin) end # For len < 2 @@ -704,7 +728,7 @@ function _linspace1(::Type{T}, start, stop, len::Integer) where T<:IEEEFloat # The output type must be consistent with steprangelen_hp if T<:Union{Float32,Float16} return StepRangeLen{T}(Float64(start), Float64(start) - Float64(stop), len, 1) - else + else # T == Float64 return StepRangeLen(TwicePrecision(start, zero(T)), TwicePrecision(start, -stop), len, 1) end end @@ -713,8 +737,8 @@ end ### Numeric utilities -# Approximate x with a rational representation. Guaranteed to return, -# but not guaranteed to return a precise answer. +# Approximate x with a rational representation as a pair of Int values. +# Guaranteed to return, but not guaranteed to return a precise answer. # https://en.wikipedia.org/wiki/Continued_fraction#Best_rational_approximations function rat(x) y = x @@ -722,7 +746,7 @@ function rat(x) b = c = 0 m = maxintfloat(narrow(typeof(x)), Int) while abs(y) <= m - f = trunc(Int,y) + f = trunc(Int, y) y -= f a, c = f*a + c, a b, d = f*b + d, b diff --git a/test/ranges.jl b/test/ranges.jl index b622fc05b3ca6..42a1c8a74ff6f 100644 --- a/test/ranges.jl +++ b/test/ranges.jl @@ -652,8 +652,8 @@ end @test broadcast(-, T(1):2:6, 0.3) === T(1)-0.3:2:5-0.3 is_unsigned = T <: Unsigned is_unsigned && @test length(broadcast(-, T(1):3, 2)) === length(T(1)-2:T(3)-2) - @test broadcast(-, T(1):3) == -T(1):-1:-T(3) broken=is_unsigned - @test broadcast(-, 2, T(1):3) == T(1):-1:-T(1) broken=is_unsigned + @test broadcast(-, T(1):3) == -T(1):-T(1):-T(3) + @test broadcast(-, 2, T(1):3) == T(1):-T(1):-T(1) end @testset "operations between ranges and arrays" for T in (Int, UInt, Int128) @test all(([T(1):5;] + (T(5):-1:1)) .=== T(6)) @@ -1108,10 +1108,11 @@ end # repr/show should display the range nicely # to test print_range in range.jl replrepr(x) = repr("text/plain", x; context=IOContext(stdout, :limit=>true, :displaysize=>(24, 80))) + nb = Sys.WORD_SIZE @test replrepr(1:4) == "1:4" @test repr("text/plain", 1:4) == "1:4" @test repr("text/plain", range(1, stop=5, length=7)) == "1.0:0.6666666666666666:5.0" - @test repr("text/plain", LinRange{Float64}(1,5,7)) == "7-element LinRange{Float64}:\n 1.0,1.66667,2.33333,3.0,3.66667,4.33333,5.0" + @test repr("text/plain", LinRange{Float64}(1,5,7)) == "7-element LinRange{Float64, Int$nb}:\n 1.0,1.66667,2.33333,3.0,3.66667,4.33333,5.0" @test repr(range(1, stop=5, length=7)) == "1.0:0.6666666666666666:5.0" @test repr(LinRange{Float64}(1,5,7)) == "range(1.0, stop=5.0, length=7)" @test replrepr(0:100.) == "0.0:1.0:100.0" @@ -1119,7 +1120,7 @@ end # only examines spacing of the left and right edges of the range, sufficient # to cover the designated screen size. @test replrepr(range(0, stop=100, length=10000)) == "0.0:0.010001000100010001:100.0" - @test replrepr(LinRange{Float64}(0,100, 10000)) == "10000-element LinRange{Float64}:\n 0.0,0.010001,0.020002,0.030003,0.040004,…,99.95,99.96,99.97,99.98,99.99,100.0" + @test replrepr(LinRange{Float64}(0,100, 10000)) == "10000-element LinRange{Float64, Int$nb}:\n 0.0,0.010001,0.020002,0.030003,0.040004,…,99.95,99.96,99.97,99.98,99.99,100.0" @test sprint(show, UnitRange(1, 2)) == "1:2" @test sprint(show, StepRange(1, 2, 5)) == "1:2:5" @@ -2045,3 +2046,7 @@ end @test_throws BoundsError r[Base.IdentityUnitRange(-1:100)] end end + +@test length(range(1, 100, length=big(100)^100)) == big(100)^100 +@test length(range(big(1), big(100)^100, length=big(100)^100)) == big(100)^100 +@test length(0 * (1:big(100)^100)) == big(100)^100 From eeaadce90161c531ef50a7adc24160cda0541844 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Wed, 14 Jul 2021 15:30:31 -0400 Subject: [PATCH 66/74] atomics: disable unordered RMW ordering This is not a particularly meaningful combination (LLVM dislikes it). (cherry picked from commit f7fdcac11a30ea0a794bb54a0cb00e13ad77536d) --- src/builtins.c | 2 +- test/atomics.jl | 26 +++++++++++++------------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/builtins.c b/src/builtins.c index a6bcad48ab731..b186aadbed5d2 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -812,7 +812,7 @@ enum jl_memory_order jl_get_atomic_order(jl_sym_t *order, char loading, char sto { if (order == not_atomic_sym) return jl_memory_order_notatomic; - if (order == unordered_sym && (loading || storing)) + if (order == unordered_sym && (loading ^ storing)) return jl_memory_order_unordered; if (order == monotonic_sym && (loading || storing)) return jl_memory_order_monotonic; diff --git a/test/atomics.jl b/test/atomics.jl index e4202b5ce1aea..4c32fc12d87ed 100644 --- a/test/atomics.jl +++ b/test/atomics.jl @@ -184,7 +184,7 @@ test_field_operators(ARefxy{Float64}(123_10, 123_20)) @test getfield(r, :y) === x @test_throws ConcurrencyViolationError("invalid atomic ordering") swapfield!(r, :y, y, :u) - @test_throws ConcurrencyViolationError("swapfield!: non-atomic field cannot be written atomically") swapfield!(r, :y, y, :unordered) + @test_throws ConcurrencyViolationError("invalid atomic ordering") swapfield!(r, :y, y, :unordered) @test_throws ConcurrencyViolationError("swapfield!: non-atomic field cannot be written atomically") swapfield!(r, :y, y, :monotonic) @test_throws ConcurrencyViolationError("swapfield!: non-atomic field cannot be written atomically") swapfield!(r, :y, y, :acquire) @test_throws ConcurrencyViolationError("swapfield!: non-atomic field cannot be written atomically") swapfield!(r, :y, y, :release) @@ -193,7 +193,7 @@ test_field_operators(ARefxy{Float64}(123_10, 123_20)) @test swapfield!(r, :y, y, :not_atomic) === x @test_throws ConcurrencyViolationError("invalid atomic ordering") modifyfield!(r, :y, swap, y, :u) - @test_throws ConcurrencyViolationError("modifyfield!: non-atomic field cannot be written atomically") modifyfield!(r, :y, swap, y, :unordered) + @test_throws ConcurrencyViolationError("invalid atomic ordering") modifyfield!(r, :y, swap, y, :unordered) @test_throws ConcurrencyViolationError("modifyfield!: non-atomic field cannot be written atomically") modifyfield!(r, :y, swap, y, :monotonic) @test_throws ConcurrencyViolationError("modifyfield!: non-atomic field cannot be written atomically") modifyfield!(r, :y, swap, y, :acquire) @test_throws ConcurrencyViolationError("modifyfield!: non-atomic field cannot be written atomically") modifyfield!(r, :y, swap, y, :release) @@ -202,7 +202,7 @@ test_field_operators(ARefxy{Float64}(123_10, 123_20)) @test modifyfield!(r, :y, swap, x, :not_atomic) === (y, x) @test_throws ConcurrencyViolationError("invalid atomic ordering") replacefield!(r, :y, y, y, :u, :not_atomic) - @test_throws ConcurrencyViolationError("replacefield!: non-atomic field cannot be written atomically") replacefield!(r, :y, y, y, :unordered, :not_atomic) + @test_throws ConcurrencyViolationError("invalid atomic ordering") replacefield!(r, :y, y, y, :unordered, :not_atomic) @test_throws ConcurrencyViolationError("replacefield!: non-atomic field cannot be written atomically") replacefield!(r, :y, y, y, :monotonic, :not_atomic) @test_throws ConcurrencyViolationError("replacefield!: non-atomic field cannot be written atomically") replacefield!(r, :y, y, y, :acquire, :not_atomic) @test_throws ConcurrencyViolationError("replacefield!: non-atomic field cannot be written atomically") replacefield!(r, :y, y, y, :release, :not_atomic) @@ -223,8 +223,8 @@ test_field_operators(ARefxy{Float64}(123_10, 123_20)) @test_throws ConcurrencyViolationError("invalid atomic ordering") swapfield!(r, :x, x, :u) @test_throws ConcurrencyViolationError("swapfield!: atomic field cannot be written non-atomically") swapfield!(r, :x, x, :not_atomic) @test_throws ConcurrencyViolationError("swapfield!: atomic field cannot be written non-atomically") swapfield!(r, :x, x) - @test swapfield!(r, :x, x, :unordered) === y - @test swapfield!(r, :x, x, :monotonic) === x + @test_throws ConcurrencyViolationError("invalid atomic ordering") swapfield!(r, :x, x, :unordered) === y + @test swapfield!(r, :x, x, :monotonic) === y @test swapfield!(r, :x, x, :acquire) === x @test swapfield!(r, :x, x, :release) === x @test swapfield!(r, :x, x, :acquire_release) === x @@ -233,7 +233,7 @@ test_field_operators(ARefxy{Float64}(123_10, 123_20)) @test_throws ConcurrencyViolationError("invalid atomic ordering") modifyfield!(r, :x, swap, x, :u) @test_throws ConcurrencyViolationError("modifyfield!: atomic field cannot be written non-atomically") modifyfield!(r, :x, swap, x, :not_atomic) @test_throws ConcurrencyViolationError("modifyfield!: atomic field cannot be written non-atomically") modifyfield!(r, :x, swap, x) - @test modifyfield!(r, :x, swap, x, :unordered) === (x, x) + @test_throws ConcurrencyViolationError("invalid atomic ordering") modifyfield!(r, :x, swap, x, :unordered) @test modifyfield!(r, :x, swap, x, :monotonic) === (x, x) @test modifyfield!(r, :x, swap, x, :acquire) === (x, x) @test modifyfield!(r, :x, swap, x, :release) === (x, x) @@ -243,7 +243,7 @@ test_field_operators(ARefxy{Float64}(123_10, 123_20)) @test_throws ConcurrencyViolationError("invalid atomic ordering") replacefield!(r, :x, x, x, :u, :not_atomic) @test_throws ConcurrencyViolationError("replacefield!: atomic field cannot be written non-atomically") replacefield!(r, :x, x, x) @test_throws ConcurrencyViolationError("replacefield!: atomic field cannot be written non-atomically") replacefield!(r, :x, y, x, :not_atomic, :not_atomic) - @test_throws ConcurrencyViolationError("replacefield!: atomic field cannot be accessed non-atomically") replacefield!(r, :x, x, x, :unordered, :not_atomic) + @test_throws ConcurrencyViolationError("invalid atomic ordering") replacefield!(r, :x, x, x, :unordered, :not_atomic) @test_throws ConcurrencyViolationError("replacefield!: atomic field cannot be accessed non-atomically") replacefield!(r, :x, x, x, :monotonic, :not_atomic) @test_throws ConcurrencyViolationError("replacefield!: atomic field cannot be accessed non-atomically") replacefield!(r, :x, x, x, :acquire, :not_atomic) @test_throws ConcurrencyViolationError("replacefield!: atomic field cannot be accessed non-atomically") replacefield!(r, :x, x, x, :release, :not_atomic) @@ -288,21 +288,21 @@ end Base.convert(T::Type{<:UndefComplex}, S) = T() @noinline function _test_field_undef(r) r = r[] - T = fieldtype(typeof(r), :x) - x = convert(T, 12345_10) + TT = fieldtype(typeof(r), :x) + x = convert(TT, 12345_10) @test_throws UndefRefError getfield(r, :x) @test_throws UndefRefError getfield(r, :x, :sequentially_consistent) @test_throws UndefRefError modifyfield!(r, :x, add, 1, :sequentially_consistent) - @test_throws (T === Any ? UndefRefError : TypeError) replacefield!(r, :x, 1, 1.0, :sequentially_consistent) + @test_throws (TT === Any ? UndefRefError : TypeError) replacefield!(r, :x, 1, 1.0, :sequentially_consistent) @test_throws UndefRefError replacefield!(r, :x, 1, x, :sequentially_consistent) @test_throws UndefRefError getfield(r, :x, :sequentially_consistent) @test_throws UndefRefError swapfield!(r, :x, x, :sequentially_consistent) @test getfield(r, :x, :sequentially_consistent) === x === getfield(r, :x) nothing end -@noinline function test_field_undef(T) - _test_field_undef(Ref(T())) - _test_field_undef(Ref{Any}(T())) +@noinline function test_field_undef(TT) + _test_field_undef(Ref(TT())) + _test_field_undef(Ref{Any}(TT())) nothing end test_field_undef(ARefxy{BigInt}) From 5fa4b6a7a963a318863d7d887bd30b2e48d7bfde Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Wed, 14 Jul 2021 16:22:39 -0400 Subject: [PATCH 67/74] codegen: fix some atomic return types (cherry picked from commit 84641013fdd38973c153ab97cf821742063e6905) --- src/cgutils.cpp | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/cgutils.cpp b/src/cgutils.cpp index 8c7bdad2a5903..4ae6c4b21594a 100644 --- a/src/cgutils.cpp +++ b/src/cgutils.cpp @@ -1549,10 +1549,25 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx, bool needlock, bool issetfield, bool isreplacefield, bool maybe_null_if_boxed) { assert(!needlock || parent != nullptr); - jl_cgval_t oldval = rhs; Type *elty = isboxed ? T_prjlvalue : julia_type_to_llvm(ctx, jltype); - if (type_is_ghost(elty)) - return oldval; + if (type_is_ghost(elty)) { + if (isStrongerThanMonotonic(Order)) + ctx.builder.CreateFence(Order); + if (issetfield) { + return rhs; + } + else if (isreplacefield) { + Value *Success = emit_f_is(ctx, cmp, ghostValue(jltype)); + Success = ctx.builder.CreateZExt(Success, T_int8); + jl_cgval_t argv[2] = {ghostValue(jltype), mark_julia_type(ctx, Success, false, jl_bool_type)}; + // TODO: do better here + Value *instr = emit_jlcall(ctx, jltuple_func, V_rnull, argv, 2, JLCALL_F_CC); + return mark_julia_type(ctx, instr, true, jl_any_type); + } + else { + return ghostValue(jltype); + } + } Value *intcast = nullptr; if (!isboxed && Order != AtomicOrdering::NotAtomic && !elty->isIntOrPtrTy()) { const DataLayout &DL = jl_data_layout; @@ -1590,6 +1605,7 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx, BasicBlock *DoneBB = issetfield || (!isreplacefield && !isboxed) ? nullptr : BasicBlock::Create(jl_LLVMContext, "done_xchg", ctx.f); if (needlock) emit_lockstate_value(ctx, parent, true); + jl_cgval_t oldval = rhs; if (issetfield || Order == AtomicOrdering::NotAtomic) { if (!issetfield) { instr = ctx.builder.CreateAlignedLoad(elty, ptr, Align(alignment)); @@ -3230,6 +3246,12 @@ static jl_cgval_t emit_setfield(jl_codectx_t &ctx, } if (needlock) emit_lockstate_value(ctx, strct, false); + if (isreplacefield) { + jl_cgval_t argv[2] = {oldval, mark_julia_type(ctx, Success, false, jl_bool_type)}; + // TODO: do better here + Value *instr = emit_jlcall(ctx, jltuple_func, V_rnull, argv, 2, JLCALL_F_CC); + oldval = mark_julia_type(ctx, instr, true, jl_any_type); + } return oldval; } else { From e04e3e1932785d27a252ba95f8ebedd37f624094 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Wed, 14 Jul 2021 15:32:18 -0400 Subject: [PATCH 68/74] codegen: optimize setfield/arrayset with inline isa test (cherry picked from commit 471e89385fdff8e0033bbd6e795be6750e380ac7) --- src/codegen.cpp | 196 +++++++++++++++++++++++++----------------------- 1 file changed, 101 insertions(+), 95 deletions(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index acf7f1167cb14..e6505f7b67870 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -2880,7 +2880,7 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, else if (f == jl_builtin_arrayset && nargs >= 4) { const jl_cgval_t &ary = argv[2]; - const jl_cgval_t &val = argv[3]; + jl_cgval_t val = argv[3]; bool indices_ok = true; for (size_t i = 4; i <= nargs; i++) { if (argv[i].typ != (jl_value_t*)jl_long_type) { @@ -2893,101 +2893,103 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, jl_value_t *ety = jl_tparam0(aty_dt); jl_value_t *ndp = jl_tparam1(aty_dt); if (!jl_has_free_typevars(ety) && (jl_is_long(ndp) || nargs == 4)) { - if (jl_subtype(val.typ, ety)) { // TODO: probably should just convert this to a type-assert - size_t elsz = 0, al = 0; - int union_max = jl_islayout_inline(ety, &elsz, &al); - bool isboxed = (union_max == 0); - if (isboxed) - ety = (jl_value_t*)jl_any_type; - jl_value_t *ary_ex = jl_exprarg(ex, 2); - ssize_t nd = jl_is_long(ndp) ? jl_unbox_long(ndp) : -1; - jl_value_t *boundscheck = argv[1].constant; - emit_typecheck(ctx, argv[1], (jl_value_t*)jl_bool_type, "arrayset"); - Value *idx = emit_array_nd_index(ctx, ary, ary_ex, nd, &argv[4], nargs - 3, boundscheck); - if (!isboxed && jl_is_datatype(ety) && jl_datatype_size(ety) == 0) { - // no-op - } - else { - PHINode *data_owner = NULL; // owner object against which the write barrier must check - if (isboxed || (jl_is_datatype(ety) && ((jl_datatype_t*)ety)->layout->npointers > 0)) { // if elements are just bits, don't need a write barrier - Value *aryv = boxed(ctx, ary); - Value *flags = emit_arrayflags(ctx, ary); - // the owner of the data is ary itself except if ary->how == 3 - flags = ctx.builder.CreateAnd(flags, 3); - Value *is_owned = ctx.builder.CreateICmpEQ(flags, ConstantInt::get(T_int16, 3)); - BasicBlock *curBB = ctx.builder.GetInsertBlock(); - BasicBlock *ownedBB = BasicBlock::Create(jl_LLVMContext, "array_owned", ctx.f); - BasicBlock *mergeBB = BasicBlock::Create(jl_LLVMContext, "merge_own", ctx.f); - ctx.builder.CreateCondBr(is_owned, ownedBB, mergeBB); - ctx.builder.SetInsertPoint(ownedBB); - // load owner pointer - Instruction *own_ptr; - if (jl_is_long(ndp)) { - own_ptr = ctx.builder.CreateAlignedLoad(T_prjlvalue, - ctx.builder.CreateConstInBoundsGEP1_32(T_prjlvalue, - emit_bitcast(ctx, decay_derived(ctx, aryv), T_pprjlvalue), - jl_array_data_owner_offset(nd) / sizeof(jl_value_t*)), - Align(sizeof(void*))); - tbaa_decorate(tbaa_const, maybe_mark_load_dereferenceable(own_ptr, false, (jl_value_t*)jl_array_any_type)); - } - else { - own_ptr = ctx.builder.CreateCall( - prepare_call(jlarray_data_owner_func), - {aryv}); - } - ctx.builder.CreateBr(mergeBB); - ctx.builder.SetInsertPoint(mergeBB); - data_owner = ctx.builder.CreatePHI(T_prjlvalue, 2); - data_owner->addIncoming(aryv, curBB); - data_owner->addIncoming(own_ptr, ownedBB); + if (!jl_subtype(val.typ, ety)) { + emit_typecheck(ctx, val, ety, "arrayset"); + val = update_julia_type(ctx, val, ety); + } + size_t elsz = 0, al = 0; + int union_max = jl_islayout_inline(ety, &elsz, &al); + bool isboxed = (union_max == 0); + if (isboxed) + ety = (jl_value_t*)jl_any_type; + jl_value_t *ary_ex = jl_exprarg(ex, 2); + ssize_t nd = jl_is_long(ndp) ? jl_unbox_long(ndp) : -1; + jl_value_t *boundscheck = argv[1].constant; + emit_typecheck(ctx, argv[1], (jl_value_t*)jl_bool_type, "arrayset"); + Value *idx = emit_array_nd_index(ctx, ary, ary_ex, nd, &argv[4], nargs - 3, boundscheck); + if (!isboxed && jl_is_datatype(ety) && jl_datatype_size(ety) == 0) { + // no-op + } + else { + PHINode *data_owner = NULL; // owner object against which the write barrier must check + if (isboxed || (jl_is_datatype(ety) && ((jl_datatype_t*)ety)->layout->npointers > 0)) { // if elements are just bits, don't need a write barrier + Value *aryv = boxed(ctx, ary); + Value *flags = emit_arrayflags(ctx, ary); + // the owner of the data is ary itself except if ary->how == 3 + flags = ctx.builder.CreateAnd(flags, 3); + Value *is_owned = ctx.builder.CreateICmpEQ(flags, ConstantInt::get(T_int16, 3)); + BasicBlock *curBB = ctx.builder.GetInsertBlock(); + BasicBlock *ownedBB = BasicBlock::Create(jl_LLVMContext, "array_owned", ctx.f); + BasicBlock *mergeBB = BasicBlock::Create(jl_LLVMContext, "merge_own", ctx.f); + ctx.builder.CreateCondBr(is_owned, ownedBB, mergeBB); + ctx.builder.SetInsertPoint(ownedBB); + // load owner pointer + Instruction *own_ptr; + if (jl_is_long(ndp)) { + own_ptr = ctx.builder.CreateAlignedLoad(T_prjlvalue, + ctx.builder.CreateConstInBoundsGEP1_32(T_prjlvalue, + emit_bitcast(ctx, decay_derived(ctx, aryv), T_pprjlvalue), + jl_array_data_owner_offset(nd) / sizeof(jl_value_t*)), + Align(sizeof(void*))); + tbaa_decorate(tbaa_const, maybe_mark_load_dereferenceable(own_ptr, false, (jl_value_t*)jl_array_any_type)); } - if (!isboxed && jl_is_uniontype(ety)) { - Type *AT = ArrayType::get(IntegerType::get(jl_LLVMContext, 8 * al), (elsz + al - 1) / al); - Value *data = emit_bitcast(ctx, emit_arrayptr(ctx, ary, ary_ex), AT->getPointerTo()); - // compute tindex from val - jl_cgval_t rhs_union = convert_julia_type(ctx, val, ety); - Value *tindex = compute_tindex_unboxed(ctx, rhs_union, ety); - tindex = ctx.builder.CreateNUWSub(tindex, ConstantInt::get(T_int8, 1)); - Value *ndims = (nd == -1 ? emit_arrayndims(ctx, ary) : ConstantInt::get(T_int16, nd)); - Value *is_vector = ctx.builder.CreateICmpEQ(ndims, ConstantInt::get(T_int16, 1)); - Value *offset = emit_arrayoffset(ctx, ary, nd); - Value *selidx_v = ctx.builder.CreateSub(emit_vectormaxsize(ctx, ary), ctx.builder.CreateZExt(offset, T_size)); - Value *selidx_m = emit_arraylen(ctx, ary); - Value *selidx = ctx.builder.CreateSelect(is_vector, selidx_v, selidx_m); - Value *ptindex = ctx.builder.CreateInBoundsGEP(AT, data, selidx); - ptindex = emit_bitcast(ctx, ptindex, T_pint8); - ptindex = ctx.builder.CreateInBoundsGEP(T_int8, ptindex, offset); - ptindex = ctx.builder.CreateInBoundsGEP(T_int8, ptindex, idx); - tbaa_decorate(tbaa_arrayselbyte, ctx.builder.CreateStore(tindex, ptindex)); - if (jl_is_datatype(val.typ) && jl_datatype_size(val.typ) == 0) { - // no-op - } - else { - // copy data - Value *addr = ctx.builder.CreateInBoundsGEP(AT, data, idx); - emit_unionmove(ctx, addr, tbaa_arraybuf, val, nullptr); - } + else { + own_ptr = ctx.builder.CreateCall( + prepare_call(jlarray_data_owner_func), + {aryv}); + } + ctx.builder.CreateBr(mergeBB); + ctx.builder.SetInsertPoint(mergeBB); + data_owner = ctx.builder.CreatePHI(T_prjlvalue, 2); + data_owner->addIncoming(aryv, curBB); + data_owner->addIncoming(own_ptr, ownedBB); + } + if (!isboxed && jl_is_uniontype(ety)) { + Type *AT = ArrayType::get(IntegerType::get(jl_LLVMContext, 8 * al), (elsz + al - 1) / al); + Value *data = emit_bitcast(ctx, emit_arrayptr(ctx, ary, ary_ex), AT->getPointerTo()); + // compute tindex from val + jl_cgval_t rhs_union = convert_julia_type(ctx, val, ety); + Value *tindex = compute_tindex_unboxed(ctx, rhs_union, ety); + tindex = ctx.builder.CreateNUWSub(tindex, ConstantInt::get(T_int8, 1)); + Value *ndims = (nd == -1 ? emit_arrayndims(ctx, ary) : ConstantInt::get(T_int16, nd)); + Value *is_vector = ctx.builder.CreateICmpEQ(ndims, ConstantInt::get(T_int16, 1)); + Value *offset = emit_arrayoffset(ctx, ary, nd); + Value *selidx_v = ctx.builder.CreateSub(emit_vectormaxsize(ctx, ary), ctx.builder.CreateZExt(offset, T_size)); + Value *selidx_m = emit_arraylen(ctx, ary); + Value *selidx = ctx.builder.CreateSelect(is_vector, selidx_v, selidx_m); + Value *ptindex = ctx.builder.CreateInBoundsGEP(AT, data, selidx); + ptindex = emit_bitcast(ctx, ptindex, T_pint8); + ptindex = ctx.builder.CreateInBoundsGEP(T_int8, ptindex, offset); + ptindex = ctx.builder.CreateInBoundsGEP(T_int8, ptindex, idx); + tbaa_decorate(tbaa_arrayselbyte, ctx.builder.CreateStore(tindex, ptindex)); + if (jl_is_datatype(val.typ) && jl_datatype_size(val.typ) == 0) { + // no-op } else { - typed_store(ctx, - emit_arrayptr(ctx, ary, ary_ex, isboxed), - idx, val, jl_cgval_t(), ety, - isboxed ? tbaa_ptrarraybuf : tbaa_arraybuf, - ctx.aliasscope, - data_owner, - isboxed, - isboxed ? AtomicOrdering::Unordered : AtomicOrdering::NotAtomic, // TODO: we should do this for anything with CountTrackedPointers(elty).count > 0 - isboxed ? AtomicOrdering::Unordered : AtomicOrdering::NotAtomic, // TODO: we should do this for anything with CountTrackedPointers(elty).count > 0 - 0, - false, - true, - false, - false); + // copy data + Value *addr = ctx.builder.CreateInBoundsGEP(AT, data, idx); + emit_unionmove(ctx, addr, tbaa_arraybuf, val, nullptr); } } - *ret = ary; - return true; + else { + typed_store(ctx, + emit_arrayptr(ctx, ary, ary_ex, isboxed), + idx, val, jl_cgval_t(), ety, + isboxed ? tbaa_ptrarraybuf : tbaa_arraybuf, + ctx.aliasscope, + data_owner, + isboxed, + isboxed ? AtomicOrdering::Unordered : AtomicOrdering::NotAtomic, // TODO: we should do this for anything with CountTrackedPointers(elty).count > 0 + isboxed ? AtomicOrdering::Unordered : AtomicOrdering::NotAtomic, // TODO: we should do this for anything with CountTrackedPointers(elty).count > 0 + 0, + false, + true, + false, + false); + } } + *ret = ary; + return true; } } } @@ -3131,13 +3133,13 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, const jl_cgval_t undefval; const jl_cgval_t &obj = argv[1]; const jl_cgval_t &fld = argv[2]; - const jl_cgval_t &val = argv[isreplacefield ? 4 : 3]; + jl_cgval_t val = argv[isreplacefield ? 4 : 3]; const jl_cgval_t &cmp = isreplacefield ? argv[3] : undefval; enum jl_memory_order order = jl_memory_order_notatomic; + const std::string fname = issetfield ? "setfield!" : isreplacefield ? "replacefield!" : "swapfield!"; if (nargs >= (isreplacefield ? 5 : 4)) { const jl_cgval_t &ord = argv[isreplacefield ? 5 : 4]; - emit_typecheck(ctx, ord, (jl_value_t*)jl_symbol_type, - issetfield ? "setfield!" : isreplacefield ? "replacefield!" : "swapfield!"); + emit_typecheck(ctx, ord, (jl_value_t*)jl_symbol_type, fname); if (!ord.constant) return false; order = jl_get_atomic_order((jl_sym_t*)ord.constant, !issetfield, true); @@ -3145,7 +3147,7 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, enum jl_memory_order fail_order = order; if (isreplacefield && nargs == 6) { const jl_cgval_t &ord = argv[6]; - emit_typecheck(ctx, ord, (jl_value_t*)jl_symbol_type, "replacefield!"); + emit_typecheck(ctx, ord, (jl_value_t*)jl_symbol_type, fname); if (!ord.constant) return false; fail_order = jl_get_atomic_order((jl_sym_t*)ord.constant, true, false); @@ -3169,7 +3171,11 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, } if (idx != -1) { jl_value_t *ft = jl_svecref(uty->types, idx); - if (!jl_has_free_typevars(ft) && jl_subtype(val.typ, ft)) { + if (!jl_has_free_typevars(ft)) { + if (!jl_subtype(val.typ, ft)) { + emit_typecheck(ctx, val, ft, fname); + val = update_julia_type(ctx, val, ft); + } // TODO: attempt better codegen for approximate types bool isboxed = jl_field_isptr(uty, idx); bool isatomic = jl_field_isatomic(uty, idx); From 3f5e41b5b7ec0965b93ccb9f1cd97214db0df7a5 Mon Sep 17 00:00:00 2001 From: Tim Besard Date: Tue, 27 Jul 2021 16:44:31 +0200 Subject: [PATCH 69/74] Init codegen during sysimg restore (#41676) (cherry picked from commit 2fbeef8d712ff9151370fd27a3ae07ea8b2e740d) --- src/init.c | 7 ++++--- src/staticdata.c | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/init.c b/src/init.c index 602583a9221fd..5c0ce45a77912 100644 --- a/src/init.c +++ b/src/init.c @@ -734,12 +734,13 @@ JL_DLLEXPORT void julia_init(JL_IMAGE_SEARCH rel) if (jl_options.cpu_target == NULL) jl_options.cpu_target = "native"; - if (jl_options.image_file) + if (jl_options.image_file) { jl_restore_system_image(jl_options.image_file); - else + } else { jl_init_types(); + jl_init_codegen(); + } - jl_init_codegen(); jl_init_common_symbols(); jl_init_flisp(); jl_init_serializer(); diff --git a/src/staticdata.c b/src/staticdata.c index d70e35542de2a..8fa1613b075a8 100644 --- a/src/staticdata.c +++ b/src/staticdata.c @@ -1839,6 +1839,7 @@ static void jl_restore_system_image_from_stream(ios_t *f) JL_GC_DISABLED } s.s = &sysimg; + jl_init_codegen(); jl_update_all_fptrs(&s); // fptr relocs and registration // reinit ccallables, which require codegen to be initialized s.s = f; From be3e80709a7b6abede4bbdd595ea6d25ad896e76 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Wed, 28 Jul 2021 13:48:24 -0400 Subject: [PATCH 70/74] upgrade libuv to v2-1.42.0 (#41710) (cherry picked from commit b50bf04ac0c59ede44fd230b2e1be5f18a29654f) --- Make.inc | 4 +++ Makefile | 3 ++ contrib/refresh_checksums.mk | 5 +++ deps/checksums/libuv | 68 +++++++++++++++++------------------ deps/libuv.version | 4 +-- stdlib/LibUV_jll/Project.toml | 2 +- 6 files changed, 49 insertions(+), 37 deletions(-) diff --git a/Make.inc b/Make.inc index 3d61f5255ef1a..668507dadad2c 100644 --- a/Make.inc +++ b/Make.inc @@ -87,6 +87,10 @@ endef COMMA:=, SPACE:=$(eval) $(eval) +# force a sane / stable configuration +export LC_ALL=C +export LANG=C + # We need python for things like BB triplet recognition and relative path computation. # We don't really care about version, generally, so just find something that works: PYTHON := "$(shell which python 2>/dev/null || which python3 2>/dev/null || which python2 2>/dev/null || echo "{python|python3|python2} not found")" diff --git a/Makefile b/Makefile index 51bb09b094f1c..62afa8e685529 100644 --- a/Makefile +++ b/Makefile @@ -573,3 +573,6 @@ endif @time $(call spawn,$(build_bindir)/julia$(EXE) -e '') @time $(call spawn,$(build_bindir)/julia$(EXE) -e '') @time $(call spawn,$(build_bindir)/julia$(EXE) -e '') + +print-locale: + @locale diff --git a/contrib/refresh_checksums.mk b/contrib/refresh_checksums.mk index 1ccbb16a9ba4f..5b8a25ab79b91 100644 --- a/contrib/refresh_checksums.mk +++ b/contrib/refresh_checksums.mk @@ -8,6 +8,11 @@ SRCDIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))) JULIAHOME := $(abspath $(SRCDIR)/..) +# force a sane / stable configuration +export LC_ALL=C +export LANG=C +.SUFFIXES: + # Default target that will have everything else added to it as a dependency all: checksum pack-checksum diff --git a/deps/checksums/libuv b/deps/checksums/libuv index f03a3c6ce9a35..f3ecef6586547 100644 --- a/deps/checksums/libuv +++ b/deps/checksums/libuv @@ -1,34 +1,34 @@ -libuv-fb3e3364c33ae48c827f6b103e05c3f0e78b79a9.tar.gz/md5/dc93ae5119c8934f374570342ef036ed -libuv-fb3e3364c33ae48c827f6b103e05c3f0e78b79a9.tar.gz/sha512/29947c236aef8931be4767df1cd8404ee9b036ee107b31cbce6fad9a97743df57d068b15bc4bd00320b9b81cd879258a9ec9dc675853e424ccdb8d6bdd226240 -LibUV.v2.0.1+2.aarch64-apple-darwin.tar.gz/md5/ed00585eb80fd82c014e2a431269ccec -LibUV.v2.0.1+2.aarch64-apple-darwin.tar.gz/sha512/a98ffde4ff49a71699f798622c62b5f95d0dc010f1de88ad57ee437baa73cb25e263a8a6c4de86364fb31076993326d9bd0223db3e1ecf6904c1aa6e7e1f0120 -LibUV.v2.0.1+2.aarch64-linux-gnu.tar.gz/md5/3e75495795d5a4eee8ec9c1619a5caaa -LibUV.v2.0.1+2.aarch64-linux-gnu.tar.gz/sha512/c0f1396ccc7784772d4c40f3a62d6bb22c6859a3258b07727348f436b7991a8f6d51ec46c09569f17a7bd600a321ab3b3cd59538d39c228cd3e205c33e755a51 -LibUV.v2.0.1+2.aarch64-linux-musl.tar.gz/md5/c2899ea791cfcd37ff85c1182330168e -LibUV.v2.0.1+2.aarch64-linux-musl.tar.gz/sha512/b340ff4e28a5e566ee2640926265b2070acfcc4b3c87fc2e414e2b2a9ff23be852d92ff4f51e36e21de029f23bca5524e7e267ba091401b070f4d5cd9bd03c54 -LibUV.v2.0.1+2.armv6l-linux-gnueabihf.tar.gz/md5/6b6c080a88050051100af58a4e96f25d -LibUV.v2.0.1+2.armv6l-linux-gnueabihf.tar.gz/sha512/936a4f4baf21a0fe7492bc3fab3475f653824daa184030df764af1eb5e71d152aa5dd3449b1cf31f77a460169853d7371597056e641c440c7b3d4f5c6be1ce10 -LibUV.v2.0.1+2.armv6l-linux-musleabihf.tar.gz/md5/032010ad683931906d2467753cebea9e -LibUV.v2.0.1+2.armv6l-linux-musleabihf.tar.gz/sha512/b8050662775d75e59b072c688ae44f7a3d3f54d114270902a825e01f4d74c8e131a3a75cd95e31b9ebf4488d64ff6170a67e5986e02e5fcb105bf5d3cc28706b -LibUV.v2.0.1+2.armv7l-linux-gnueabihf.tar.gz/md5/e558bedc0b69d6575e43df0eec958ad9 -LibUV.v2.0.1+2.armv7l-linux-gnueabihf.tar.gz/sha512/d3404b20b7e8e8fe935ca1e7da55823a6ff6703c822acf622638dc5c744bfefe1745e8e3a67054abc3aec0c10793ac46dbab29ccf7269d8a3a0d857e3a1a93e7 -LibUV.v2.0.1+2.armv7l-linux-musleabihf.tar.gz/md5/1aa605d9930ba63874483defb35a96ba -LibUV.v2.0.1+2.armv7l-linux-musleabihf.tar.gz/sha512/927e710191e6b8d1c09054780b4af6336c6744ceb0885c7a5a0cec5e08bfb0d53ede75cc8bb145fda08f720d98a77e102a2903e08a0fef75a0b630631db6f35e -LibUV.v2.0.1+2.i686-linux-gnu.tar.gz/md5/4ec3415ef12615581f8b26ec374a35bf -LibUV.v2.0.1+2.i686-linux-gnu.tar.gz/sha512/fd37bb83cda297ec80332cdaed2a704ea43c3ec72fb539042ef09aa510275a0418c750278fca9e463bdecdca957f8457103f0be6eeae1017387141eb2b906694 -LibUV.v2.0.1+2.i686-linux-musl.tar.gz/md5/f24ea24837ef06be346d239cbb33ae7e -LibUV.v2.0.1+2.i686-linux-musl.tar.gz/sha512/e9388568b20fa71d95e331a336aa3b17396e87d99aef6d752cb48416cdc9501e2ea887702a5765a22dcf6b5f7b730f5666ed3a639e7fe0113e9032f0d760b352 -LibUV.v2.0.1+2.i686-w64-mingw32.tar.gz/md5/890d1f7963a5dc927c15f8433b69dcf7 -LibUV.v2.0.1+2.i686-w64-mingw32.tar.gz/sha512/7e7d2b6405bbb1b62725a61d649fcbd53c2dcb65b8a6deea5a186717f88dbab4198a0f58d4223500aa991976725f8e1c4272ab29866174c5f555ba75a2e9b0ee -LibUV.v2.0.1+2.powerpc64le-linux-gnu.tar.gz/md5/7fa0d0e9344f4a4c4d5075ec5d368b0a -LibUV.v2.0.1+2.powerpc64le-linux-gnu.tar.gz/sha512/b5587e9e1072bc6becd5d1354294a3afcfda1c52e9a5f56387d43c7300369106059a2bac8669a919ce25d888b2302711c7433a82e366648935481568420daeef -LibUV.v2.0.1+2.x86_64-apple-darwin.tar.gz/md5/716960539cbae1e38e1cf88c2670927d -LibUV.v2.0.1+2.x86_64-apple-darwin.tar.gz/sha512/7b064d99428b312302c698e73e8a7919147c0522857a24e08d16144aea83429c5ac9526b6553697f28784457a5b417958fc5e4e28b4191861004dddc3f95566c -LibUV.v2.0.1+2.x86_64-linux-gnu.tar.gz/md5/ff70887943a3fc68eddcb66ed941417e -LibUV.v2.0.1+2.x86_64-linux-gnu.tar.gz/sha512/00610022d700dd6b33c97decea43490fcd4218fde2e57c0d6317abec046adf220fdf4d03f132938ec78af85653a5262d1344527c632c06aec53750710a6b317c -LibUV.v2.0.1+2.x86_64-linux-musl.tar.gz/md5/a5834444d0b7e7d88cc87e5eb458bca3 -LibUV.v2.0.1+2.x86_64-linux-musl.tar.gz/sha512/e2e6e6726e8ef0962c35d7ff54a60b3370cd5b927fda8b4415e8d2f19b098ed9bd00e262eb18d11a73e2e27c88aefa72c3a6e9c193d27eab436c4d9d6531cd47 -LibUV.v2.0.1+2.x86_64-unknown-freebsd.tar.gz/md5/951d9da43208d2c48eb00c7ce300b4cf -LibUV.v2.0.1+2.x86_64-unknown-freebsd.tar.gz/sha512/87e578f6cf34c9cc1c965f4958048967740b4ab530836aff33b3339c0d927beccf1f0c58f7e256c9ba98bf1fa0362186a24fcc5bb79ae1f149f86183b4b7f5c1 -LibUV.v2.0.1+2.x86_64-w64-mingw32.tar.gz/md5/4e9c2f078ed7b617a1aa447e1c44abbf -LibUV.v2.0.1+2.x86_64-w64-mingw32.tar.gz/sha512/b3b14c5d447cd742cade43b56bf3867d530dd391c105ddbd7f2b9e0e26ee6a1f3e6fa11148a9ba1540fa598b155da3e56d369a96273a5ea1343b5c3cd4821953 +LibUV.v2.0.1+3.aarch64-apple-darwin.tar.gz/md5/7c1f08965b45726099a940ab28a79207 +LibUV.v2.0.1+3.aarch64-apple-darwin.tar.gz/sha512/9f9d170fc36e2e30c53e96cdf9ae7cd4eb969905db65119627d4a9e10abb5e41aeb4ab07705d571300d44d4894c9d179c6a9450e3e6415042a6131bae0971c26 +LibUV.v2.0.1+3.aarch64-linux-gnu.tar.gz/md5/8d59850a63ea71c4007d08f7d23ceda2 +LibUV.v2.0.1+3.aarch64-linux-gnu.tar.gz/sha512/f662b36ce6e336e724c6fd03482d91a70e7ae8cfe7a1fff98cbca2cdb99b0cd3475bf32e57547097ca625c1fceb57c989871f391faea9227a6d6d4faf7649175 +LibUV.v2.0.1+3.aarch64-linux-musl.tar.gz/md5/3ad43e49a7a996b50341e7150064f13d +LibUV.v2.0.1+3.aarch64-linux-musl.tar.gz/sha512/69c6675fee6647eb7a2c8c680bd49ba31c1dcda676530af1ad1ca979c0cf8d9c908e0cb246608718d4bbca4d73174751c608aa80e3f11557ed4d05cc1d270021 +LibUV.v2.0.1+3.armv6l-linux-gnueabihf.tar.gz/md5/fec375c1c45fbd1b2eb22fbd5f727e5f +LibUV.v2.0.1+3.armv6l-linux-gnueabihf.tar.gz/sha512/1b279406cdb43bf1c3fd6b1d2d24fe9b5ca75a65212b5720d5406af26a6b7551b18efb0471c884e98e97c50693412344fd733c3ef19ea8fecf1c2c26ae888492 +LibUV.v2.0.1+3.armv6l-linux-musleabihf.tar.gz/md5/07790f330f3394d0a3ea47aa56529be1 +LibUV.v2.0.1+3.armv6l-linux-musleabihf.tar.gz/sha512/4fd4bf7c1b333907fbbbfdca213c91cb6b387e56886b6349271d7a3c1ddb3f9349f0799c60178de507e039289662c310829d81be804c5076ce9ae16eb61c8cb1 +LibUV.v2.0.1+3.armv7l-linux-gnueabihf.tar.gz/md5/2ce38a69564e279b0deb32a6af1acc52 +LibUV.v2.0.1+3.armv7l-linux-gnueabihf.tar.gz/sha512/d520ef8c556db6a42534c4abdd59f4b64ebd77cdb7b2972385d6a90463e0a490ca168bb83128e66b13555128305f85d5c979a739f7c369a11f8217e49505ce0a +LibUV.v2.0.1+3.armv7l-linux-musleabihf.tar.gz/md5/034d903cb13a45278df742df23c46275 +LibUV.v2.0.1+3.armv7l-linux-musleabihf.tar.gz/sha512/f900fd47320628ac3cf0ba0b9d9408ef4e46ed508f5efc00b94b532c5d713fcf4695827f978f605b3d9f0a1db42abcd0b1fec6a6c5bb6a502ed5f0fed55f4a32 +LibUV.v2.0.1+3.i686-linux-gnu.tar.gz/md5/60c51d15d9ae2ac8418b71730dc093d0 +LibUV.v2.0.1+3.i686-linux-gnu.tar.gz/sha512/84841f6fb4c744e335d6ce25e3059d9aeeaa54b823fe714f43fa8b11caf209e539afb9605e96992d075ae16a664da6c3a3c3d4cdb905d42c0ddc8722267c19af +LibUV.v2.0.1+3.i686-linux-musl.tar.gz/md5/d70ffffd8e57dfbcb4265ad202722fca +LibUV.v2.0.1+3.i686-linux-musl.tar.gz/sha512/c76dc0df03f7a683e08313baa0d8471b45c64099e13cf71a6595cb50c9e8ff1e96c31c400f83144ee816e5a7c8f01ad6f48d8b50a6cd161e0d246737780c2a9e +LibUV.v2.0.1+3.i686-w64-mingw32.tar.gz/md5/aa634a6e49c5683dcca287f2cf1ac71e +LibUV.v2.0.1+3.i686-w64-mingw32.tar.gz/sha512/ac1b2b53cbd7e317866259c30de349c453deda2c970587e4f4b40605f966f722fe8250e9dd7677ded0c928c9398240b7e4867805bb1404fb9d0c7dfab8493c79 +LibUV.v2.0.1+3.powerpc64le-linux-gnu.tar.gz/md5/9233d6bb298bd5020b680c25f742de98 +LibUV.v2.0.1+3.powerpc64le-linux-gnu.tar.gz/sha512/172253d1e6ce888865f5fd2182aad6426ff9988313937c7abe80ccdba859289f7ec8997574bb853f9786596d90414c4a926a475c1817c17574e0dd2ea8ad68ad +LibUV.v2.0.1+3.x86_64-apple-darwin.tar.gz/md5/09b83fe0ced427136ea5680cea64b004 +LibUV.v2.0.1+3.x86_64-apple-darwin.tar.gz/sha512/1842df6b14f23cc42c1d29546aa00b4b07390646beb312092bceb00d1de855116368ddcdd4ccd8525741fb6ecd26312c90dc9342d2e1ef4d36fbb896bdd2cbd3 +LibUV.v2.0.1+3.x86_64-linux-gnu.tar.gz/md5/d54b4fbfd998228e80c42c89df2c14a1 +LibUV.v2.0.1+3.x86_64-linux-gnu.tar.gz/sha512/290b2432e72712e73f20aa0ea6f787f9ffbf9ab5e3249c708355f7d57fb3b40ec3913e0c9a7141197caf3a741d6edbb1788cdef7e1a9a8547117dcf40559e567 +LibUV.v2.0.1+3.x86_64-linux-musl.tar.gz/md5/7690b83baecf1b614f30c7c0b661d86d +LibUV.v2.0.1+3.x86_64-linux-musl.tar.gz/sha512/53950b56f87ea0acc13790bf3a82441ca4ccfcd66cf272c81915e999487e4973c8c474caa811584d5fa8873cdd18ac0944f3d6f415c483a26e38645eb1701cdb +LibUV.v2.0.1+3.x86_64-unknown-freebsd.tar.gz/md5/6d2a330a2e87b9b8564708fba963845f +LibUV.v2.0.1+3.x86_64-unknown-freebsd.tar.gz/sha512/f15daf2f5a1bda49234fe546e13f97280c843d6939c26c9f05133302ec81e38bd47a5098d4900e39290f913835cffbdaa0b2c6406d6a86dc2eb8d0159f461e9f +LibUV.v2.0.1+3.x86_64-w64-mingw32.tar.gz/md5/4f934cf8dd1d45b206af6a72c3e679f7 +LibUV.v2.0.1+3.x86_64-w64-mingw32.tar.gz/sha512/36ef56923d7cf5c31aba87fb75774ce68976f7b6b7971a4c86011da275a5472e28033a6d97b965887b7bbe335bedfb6970618b88f20c095228ffa5f783ab8eb1 +libuv-c6869fba163a1e04af64ede438a8fd0191e75e9e.tar.gz/md5/b60fc7b00bdfafcbbc66317858882058 +libuv-c6869fba163a1e04af64ede438a8fd0191e75e9e.tar.gz/sha512/197b386af51eb4456ce65e2951e033731e1194fca8bed08755a78360ebb3431ab4d8d69a75279e7995d2e4197133d613892e5b9b5d6411bffa692df35542420f diff --git a/deps/libuv.version b/deps/libuv.version index 339cba4441875..045f329a0c9f3 100644 --- a/deps/libuv.version +++ b/deps/libuv.version @@ -1,2 +1,2 @@ -LIBUV_BRANCH=julia-uv2-1.39.0 -LIBUV_SHA1=fb3e3364c33ae48c827f6b103e05c3f0e78b79a9 +LIBUV_BRANCH=julia-uv2-1.42.0 +LIBUV_SHA1=c6869fba163a1e04af64ede438a8fd0191e75e9e diff --git a/stdlib/LibUV_jll/Project.toml b/stdlib/LibUV_jll/Project.toml index d07970cd43603..6215781ec4177 100644 --- a/stdlib/LibUV_jll/Project.toml +++ b/stdlib/LibUV_jll/Project.toml @@ -1,6 +1,6 @@ name = "LibUV_jll" uuid = "183b4373-6708-53ba-ad28-60e28bb38547" -version = "2.0.1+2" +version = "2.0.1+3" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" From 84e6bb9b61c9459a525cbc49c32d8fea85eb9e20 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Thu, 29 Jul 2021 12:07:17 -0400 Subject: [PATCH 71/74] Revert "Merge pull request #38405 from JuliaLang/vc/distributed_ts" (#41722) Also reverts "fixup to pull request #38405 (#41641)" Seems to be causing hanging in CI testing. This reverts commit 5af1cf0faf10308857f319b17432b007e318516b and this reverts commit 5a1680533b461471f537f5f5d4ee3c2866b21e1f, reversing changes made to 02807b279a5e6d5acaeb7095e4c0527e2a5c190e. (cherry picked from commit 66f9b55e3bf40f03e49cd95008ba1d7c709ca127) --- stdlib/Distributed/src/cluster.jl | 66 ++++----------------- stdlib/Distributed/src/macros.jl | 10 +++- stdlib/Distributed/src/managers.jl | 2 +- stdlib/Distributed/src/messages.jl | 28 +++++---- stdlib/Distributed/src/remotecall.jl | 46 ++++---------- stdlib/Distributed/test/distributed_exec.jl | 1 - stdlib/Distributed/test/threads.jl | 63 -------------------- 7 files changed, 47 insertions(+), 169 deletions(-) delete mode 100644 stdlib/Distributed/test/threads.jl diff --git a/stdlib/Distributed/src/cluster.jl b/stdlib/Distributed/src/cluster.jl index 52400a129efb4..ebe4cac0f3bbe 100644 --- a/stdlib/Distributed/src/cluster.jl +++ b/stdlib/Distributed/src/cluster.jl @@ -95,14 +95,13 @@ end @enum WorkerState W_CREATED W_CONNECTED W_TERMINATING W_TERMINATED mutable struct Worker id::Int - msg_lock::Threads.ReentrantLock # Lock for del_msgs, add_msgs, and gcflag del_msgs::Array{Any,1} add_msgs::Array{Any,1} gcflag::Bool state::WorkerState - c_state::Threads.Condition # wait for state changes, lock for state - ct_time::Float64 # creation time - conn_func::Any # used to setup connections lazily + c_state::Condition # wait for state changes + ct_time::Float64 # creation time + conn_func::Any # used to setup connections lazily r_stream::IO w_stream::IO @@ -134,7 +133,7 @@ mutable struct Worker if haskey(map_pid_wrkr, id) return map_pid_wrkr[id] end - w=new(id, Threads.ReentrantLock(), [], [], false, W_CREATED, Threads.Condition(), time(), conn_func) + w=new(id, [], [], false, W_CREATED, Condition(), time(), conn_func) w.initialized = Event() register_worker(w) w @@ -144,16 +143,12 @@ mutable struct Worker end function set_worker_state(w, state) - lock(w.c_state) do - w.state = state - notify(w.c_state; all=true) - end + w.state = state + notify(w.c_state; all=true) end function check_worker_state(w::Worker) - lock(w.c_state) if w.state === W_CREATED - unlock(w.c_state) if !isclusterlazy() if PGRP.topology === :all_to_all # Since higher pids connect with lower pids, the remote worker @@ -173,8 +168,6 @@ function check_worker_state(w::Worker) errormonitor(t) wait_for_conn(w) end - else - unlock(w.c_state) end end @@ -193,25 +186,13 @@ function exec_conn_func(w::Worker) end function wait_for_conn(w) - lock(w.c_state) if w.state === W_CREATED - unlock(w.c_state) timeout = worker_timeout() - (time() - w.ct_time) timeout <= 0 && error("peer $(w.id) has not connected to $(myid())") - T = Threads.@spawn begin - sleep($timeout) - lock(w.c_state) do - notify(w.c_state; all=true) - end - end - errormonitor(T) - lock(w.c_state) do - wait(w.c_state) - w.state === W_CREATED && error("peer $(w.id) didn't connect to $(myid()) within $timeout seconds") - end - else - unlock(w.c_state) + @async (sleep(timeout); notify(w.c_state; all=true)) + wait(w.c_state) + w.state === W_CREATED && error("peer $(w.id) didn't connect to $(myid()) within $timeout seconds") end nothing end @@ -490,10 +471,6 @@ function addprocs_locked(manager::ClusterManager; kwargs...) # The `launch` method should add an object of type WorkerConfig for every # worker launched. It provides information required on how to connect # to it. - - # FIXME: launched should be a Channel, launch_ntfy should be a Threads.Condition - # but both are part of the public interface. This means we currently can't use - # `Threads.@spawn` in the code below. launched = WorkerConfig[] launch_ntfy = Condition() @@ -506,10 +483,7 @@ function addprocs_locked(manager::ClusterManager; kwargs...) while true if isempty(launched) istaskdone(t_launch) && break - @async begin - sleep(1) - notify(launch_ntfy) - end + @async (sleep(1); notify(launch_ntfy)) wait(launch_ntfy) end @@ -662,12 +636,7 @@ function create_worker(manager, wconfig) # require the value of config.connect_at which is set only upon connection completion for jw in PGRP.workers if (jw.id != 1) && (jw.id < w.id) - # wait for wl to join - lock(jw.c_state) do - if jw.state === W_CREATED - wait(jw.c_state) - end - end + (jw.state === W_CREATED) && wait(jw.c_state) push!(join_list, jw) end end @@ -690,12 +659,7 @@ function create_worker(manager, wconfig) end for wl in wlist - lock(wl.c_state) do - if wl.state === W_CREATED - # wait for wl to join - wait(wl.c_state) - end - end + (wl.state === W_CREATED) && wait(wl.c_state) push!(join_list, wl) end end @@ -712,11 +676,7 @@ function create_worker(manager, wconfig) @async manage(w.manager, w.id, w.config, :register) # wait for rr_ntfy_join with timeout timedout = false - @async begin - sleep($timeout) - timedout = true - put!(rr_ntfy_join, 1) - end + @async (sleep($timeout); timedout = true; put!(rr_ntfy_join, 1)) wait(rr_ntfy_join) if timedout error("worker did not connect within $timeout seconds") diff --git a/stdlib/Distributed/src/macros.jl b/stdlib/Distributed/src/macros.jl index 24a24f4c08ed4..6603d627c3409 100644 --- a/stdlib/Distributed/src/macros.jl +++ b/stdlib/Distributed/src/macros.jl @@ -1,10 +1,14 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -let nextidx = Threads.Atomic{Int}(0) +let nextidx = 0 global nextproc function nextproc() - idx = Threads.atomic_add!(nextidx, 1) - return workers()[(idx % nworkers()) + 1] + p = -1 + if p == -1 + p = workers()[(nextidx % nworkers()) + 1] + nextidx += 1 + end + p end end diff --git a/stdlib/Distributed/src/managers.jl b/stdlib/Distributed/src/managers.jl index 7ac8007951ddc..ce99d85801e17 100644 --- a/stdlib/Distributed/src/managers.jl +++ b/stdlib/Distributed/src/managers.jl @@ -160,7 +160,7 @@ function launch(manager::SSHManager, params::Dict, launched::Array, launch_ntfy: # Wait for all launches to complete. @sync for (i, (machine, cnt)) in enumerate(manager.machines) let machine=machine, cnt=cnt - @async try + @async try launch_on_machine(manager, $machine, $cnt, params, launched, launch_ntfy) catch e print(stderr, "exception launching on machine $(machine) : $(e)\n") diff --git a/stdlib/Distributed/src/messages.jl b/stdlib/Distributed/src/messages.jl index fcba709b4db4a..47f70e044a2c0 100644 --- a/stdlib/Distributed/src/messages.jl +++ b/stdlib/Distributed/src/messages.jl @@ -126,20 +126,22 @@ function flush_gc_msgs(w::Worker) if !isdefined(w, :w_stream) return end - lock(w.msg_lock) do - w.gcflag || return # early exit if someone else got to this - w.gcflag = false - msgs = w.add_msgs - w.add_msgs = Any[] - if !isempty(msgs) - remote_do(add_clients, w, msgs) - end + w.gcflag = false + new_array = Any[] + msgs = w.add_msgs + w.add_msgs = new_array + if !isempty(msgs) + remote_do(add_clients, w, msgs) + end - msgs = w.del_msgs - w.del_msgs = Any[] - if !isempty(msgs) - remote_do(del_clients, w, msgs) - end + # del_msgs gets populated by finalizers, so be very careful here about ordering of allocations + # XXX: threading requires this to be atomic + new_array = Any[] + msgs = w.del_msgs + w.del_msgs = new_array + if !isempty(msgs) + #print("sending delete of $msgs\n") + remote_do(del_clients, w, msgs) end end diff --git a/stdlib/Distributed/src/remotecall.jl b/stdlib/Distributed/src/remotecall.jl index 4f0e066ce26e0..91e5de36736bd 100644 --- a/stdlib/Distributed/src/remotecall.jl +++ b/stdlib/Distributed/src/remotecall.jl @@ -247,42 +247,22 @@ function del_clients(pairs::Vector) end end -# The task below is coalescing the `flush_gc_msgs` call -# across multiple producers, see `send_del_client`, -# and `send_add_client`. -# XXX: Is this worth the additional complexity? -# `flush_gc_msgs` has to iterate over all connected workers. -const any_gc_flag = Threads.Condition() +const any_gc_flag = Condition() function start_gc_msgs_task() - errormonitor( - Threads.@spawn begin - while true - lock(any_gc_flag) do - wait(any_gc_flag) - flush_gc_msgs() # handles throws internally - end - end - end - ) + errormonitor(@async while true + wait(any_gc_flag) + flush_gc_msgs() + end) end -# Function can be called within a finalizer function send_del_client(rr) if rr.where == myid() del_client(rr) elseif id_in_procs(rr.where) # process only if a valid worker w = worker_from_id(rr.where)::Worker - msg = (remoteref_id(rr), myid()) - # We cannot acquire locks from finalizers - Threads.@spawn begin - lock(w.msg_lock) do - push!(w.del_msgs, msg) - w.gcflag = true - end - lock(any_gc_flag) do - notify(any_gc_flag) - end - end + push!(w.del_msgs, (remoteref_id(rr), myid())) + w.gcflag = true + notify(any_gc_flag) end end @@ -308,13 +288,9 @@ function send_add_client(rr::AbstractRemoteRef, i) # to the processor that owns the remote ref. it will add_client # itself inside deserialize(). w = worker_from_id(rr.where) - lock(w.msg_lock) do - push!(w.add_msgs, (remoteref_id(rr), i)) - w.gcflag = true - end - lock(any_gc_flag) do - notify(any_gc_flag) - end + push!(w.add_msgs, (remoteref_id(rr), i)) + w.gcflag = true + notify(any_gc_flag) end end diff --git a/stdlib/Distributed/test/distributed_exec.jl b/stdlib/Distributed/test/distributed_exec.jl index 547b035e8e6b9..606b7fa81c3e7 100644 --- a/stdlib/Distributed/test/distributed_exec.jl +++ b/stdlib/Distributed/test/distributed_exec.jl @@ -1689,5 +1689,4 @@ include("splitrange.jl") # Run topology tests last after removing all workers, since a given # cluster at any time only supports a single topology. rmprocs(workers()) -include("threads.jl") include("topology.jl") diff --git a/stdlib/Distributed/test/threads.jl b/stdlib/Distributed/test/threads.jl deleted file mode 100644 index 57d99b7ea056c..0000000000000 --- a/stdlib/Distributed/test/threads.jl +++ /dev/null @@ -1,63 +0,0 @@ -using Test -using Distributed, Base.Threads -using Base.Iterators: product - -exeflags = ("--startup-file=no", - "--check-bounds=yes", - "--depwarn=error", - "--threads=2") - -function call_on(f, wid, tid) - remotecall(wid) do - t = Task(f) - ccall(:jl_set_task_tid, Cvoid, (Any, Cint), t, tid - 1) - schedule(t) - @assert threadid(t) == tid - t - end -end - -# Run function on process holding the data to only serialize the result of f. -# This becomes useful for things that cannot be serialized (e.g. running tasks) -# or that would be unnecessarily big if serialized. -fetch_from_owner(f, rr) = remotecall_fetch(f ∘ fetch, rr.where, rr) - -isdone(rr) = fetch_from_owner(istaskdone, rr) -isfailed(rr) = fetch_from_owner(istaskfailed, rr) - -@testset "RemoteChannel allows put!/take! from thread other than 1" begin - ws = ts = product(1:2, 1:2) - @testset "from worker $w1 to $w2 via 1" for (w1, w2) in ws - @testset "from thread $w1.$t1 to $w2.$t2" for (t1, t2) in ts - # We want (the default) lazyness, so that we wait for `Worker.c_state`! - procs_added = addprocs(2; exeflags, lazy=true) - @everywhere procs_added using Base.Threads - - p1 = procs_added[w1] - p2 = procs_added[w2] - chan_id = first(procs_added) - chan = RemoteChannel(chan_id) - send = call_on(p1, t1) do - put!(chan, nothing) - end - recv = call_on(p2, t2) do - take!(chan) - end - - # Wait on the spawned tasks on the owner - @sync begin - Threads.@spawn fetch_from_owner(wait, recv) - Threads.@spawn fetch_from_owner(wait, send) - end - - # Check the tasks - @test isdone(send) - @test isdone(recv) - - @test !isfailed(send) - @test !isfailed(recv) - - rmprocs(procs_added) - end - end -end From dd697eceff93abf929f928938cf8620a5aa80497 Mon Sep 17 00:00:00 2001 From: Kenta Sato Date: Mon, 2 Aug 2021 17:30:24 +0900 Subject: [PATCH 72/74] guard `isempty (close #41656) (#41752) (cherry picked from commit 4c3829d413a12c2b4a87952e0f6d1ecbbff63239) --- contrib/generate_precompile.jl | 2 +- test/misc.jl | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/contrib/generate_precompile.jl b/contrib/generate_precompile.jl index b5ded199688ee..278dda2812559 100644 --- a/contrib/generate_precompile.jl +++ b/contrib/generate_precompile.jl @@ -1,6 +1,6 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -if isempty(Base.ARGS) || Base.ARGS[1] !== "0" +if Base.isempty(Base.ARGS) || Base.ARGS[1] !== "0" Sys.__init_build() # Prevent this from being put into the Main namespace @eval Module() begin diff --git a/test/misc.jl b/test/misc.jl index e765dc9279b86..411135ac63313 100644 --- a/test/misc.jl +++ b/test/misc.jl @@ -1000,3 +1000,5 @@ let script = :(let ptr = Ptr{Cint}(ccall(:jl_mmap, Ptr{Cvoid}, @test !success(`$(Base.julia_cmd()) -e $script`) end +# issue #41656 +@test success(`$(Base.julia_cmd()) -e 'isempty(x) = true'`) From 6153a7e8378276a7ea0653d5101ff61112b50f36 Mon Sep 17 00:00:00 2001 From: Sebastian Stock <42280794+sostock@users.noreply.github.com> Date: Wed, 28 Jul 2021 11:53:28 +0200 Subject: [PATCH 73/74] Fix `length(::AbstractUnitRange)` and speed up `length(::AbstractUnitRange{<:Rational})` (#41479) * Fix length(::AbstractUnitRange), faster length(::AbstractUnitRange{<:Rational}) (cherry picked from commit 1c951f7fe8e5e923cc5f5b18c91e461b61641b14) --- base/range.jl | 17 ++++++++--------- base/rational.jl | 18 ++++++++++++++++++ test/ranges.jl | 15 ++++++++++++++- 3 files changed, 40 insertions(+), 10 deletions(-) diff --git a/base/range.jl b/base/range.jl index 9a7c74e4d4088..1ab4f2c9f99ae 100644 --- a/base/range.jl +++ b/base/range.jl @@ -663,8 +663,8 @@ function checked_length(r::OrdinalRange{T}) where T else diff = checked_sub(stop, start) end - a = Integer(div(diff, s)) - return checked_add(a, oneunit(a)) + a = div(diff, s) + return Integer(checked_add(a, oneunit(a))) end function checked_length(r::AbstractUnitRange{T}) where T @@ -672,8 +672,8 @@ function checked_length(r::AbstractUnitRange{T}) where T if isempty(r) return Integer(first(r) - first(r)) end - a = Integer(checked_add(checked_sub(last(r), first(r)))) - return checked_add(a, oneunit(a)) + a = checked_sub(last(r), first(r)) + return Integer(checked_add(a, oneunit(a))) end function length(r::OrdinalRange{T}) where T @@ -690,15 +690,14 @@ function length(r::OrdinalRange{T}) where T else diff = stop - start end - a = Integer(div(diff, s)) - return a + oneunit(a) + a = div(diff, s) + return Integer(a + oneunit(a)) end - function length(r::AbstractUnitRange{T}) where T @_inline_meta - a = Integer(last(r) - first(r)) # even when isempty, by construction (with overflow) - return a + oneunit(a) + a = last(r) - first(r) # even when isempty, by construction (with overflow) + return Integer(a + oneunit(a)) end length(r::OneTo) = Integer(r.stop - zero(r.stop)) diff --git a/base/rational.jl b/base/rational.jl index 23c9298962f53..1c83443d10df3 100644 --- a/base/rational.jl +++ b/base/rational.jl @@ -533,3 +533,21 @@ function hash(x::Rational{<:BitInteger64}, h::UInt) h = hash_integer(num, h) return h end + +# These methods are only needed for performance. Since `first(r)` and `last(r)` have the +# same denominator (because their difference is an integer), `length(r)` can be calulated +# without calling `gcd`. +function length(r::AbstractUnitRange{T}) where T<:Rational + @_inline_meta + f = first(r) + l = last(r) + return div(l.num - f.num + f.den, f.den) +end +function checked_length(r::AbstractUnitRange{T}) where T<:Rational + f = first(r) + l = last(r) + if isempty(r) + return f.num - f.num + end + return div(checked_add(checked_sub(l.num, f.num), f.den), f.den) +end diff --git a/test/ranges.jl b/test/ranges.jl index 42a1c8a74ff6f..088d5746294c6 100644 --- a/test/ranges.jl +++ b/test/ranges.jl @@ -544,6 +544,19 @@ end end end +# A number type with the overflow behavior of `UInt8`. Conversion to `Integer` returns an +# `Int32`, i.e., a type with different `typemin`/`typemax`. See #41479 +struct OverflowingReal <: Real + val::UInt8 +end +OverflowingReal(x::OverflowingReal) = x +Base.:<=(x::OverflowingReal, y::OverflowingReal) = x.val <= y.val +Base.:+(x::OverflowingReal, y::OverflowingReal) = OverflowingReal(x.val + y.val) +Base.:-(x::OverflowingReal, y::OverflowingReal) = OverflowingReal(x.val - y.val) +Base.round(x::OverflowingReal, ::RoundingMode) = x +Base.Integer(x::OverflowingReal) = Int32(x.val) +@test length(OverflowingReal(1):OverflowingReal(0)) == 0 + @testset "loops involving typemin/typemax" begin n = 0 s = 0 @@ -1095,7 +1108,7 @@ end @testset "issue 10950" begin r = 1//2:3 @test length(r) == 3 - @test_throws MethodError checked_length(r) == 3 # this would work if checked_sub is defined on Rational + @test checked_length(r) == 3 i = 1 for x in r @test x == i//2 From f8bae15e3b06196d9a42be126d2975aafbe8dea5 Mon Sep 17 00:00:00 2001 From: Sebastian Stock <42280794+sostock@users.noreply.github.com> Date: Mon, 19 Jul 2021 20:48:11 +0200 Subject: [PATCH 74/74] Fix for dimensionful numbers (#41595) (cherry picked from commit 472037839642ccd31f9ed4b540bd478d2f9d4b67) --- base/range.jl | 2 +- test/ranges.jl | 1 + test/testhelpers/Furlongs.jl | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/base/range.jl b/base/range.jl index 1ab4f2c9f99ae..07d9f598d4339 100644 --- a/base/range.jl +++ b/base/range.jl @@ -681,7 +681,7 @@ function length(r::OrdinalRange{T}) where T # s != 0, by construction, but avoids the division error later start = first(r) if s == zero(s) || isempty(r) - return Integer(start - start + zero(s)) + return Integer(div(start-start, oneunit(s))) end stop = last(r) if isless(s, zero(s)) diff --git a/test/ranges.jl b/test/ranges.jl index 088d5746294c6..d95bc6911e818 100644 --- a/test/ranges.jl +++ b/test/ranges.jl @@ -1457,6 +1457,7 @@ using .Main.Furlongs @testset "dimensional correctness" begin @test length(Vector(Furlong(2):Furlong(10))) == 9 @test length(range(Furlong(2), length=9)) == checked_length(range(Furlong(2), length=9)) == 9 + @test @inferred(length(StepRange(Furlong(2), Furlong(1), Furlong(1)))) == 0 @test Vector(Furlong(2):Furlong(1):Furlong(10)) == Vector(range(Furlong(2), step=Furlong(1), length=9)) == Furlong.(2:10) @test Vector(Furlong(1.0):Furlong(0.5):Furlong(10.0)) == Vector(Furlong(1):Furlong(0.5):Furlong(10)) == Furlong.(1:0.5:10) diff --git a/test/testhelpers/Furlongs.jl b/test/testhelpers/Furlongs.jl index f3583a532215a..67c2023a0bc84 100644 --- a/test/testhelpers/Furlongs.jl +++ b/test/testhelpers/Furlongs.jl @@ -14,7 +14,7 @@ struct Furlong{p,T<:Number} <: Number end Furlong(x::T) where {T<:Number} = Furlong{1,T}(x) Furlong(x::Furlong) = x -(::Type{T})(x::Furlong) where {T<:Number} = T(x.val)::T +(::Type{T})(x::Furlong{0}) where {T<:Number} = T(x.val)::T Furlong{p}(v::Number) where {p} = Furlong{p,typeof(v)}(v) Furlong{p}(x::Furlong{q}) where {p,q} = (@assert(p==q); Furlong{p,typeof(x.val)}(x.val)) Furlong{p,T}(x::Furlong{q}) where {T,p,q} = (@assert(p==q); Furlong{p,T}(T(x.val)))