From ba3be5f5cfb2e23d35d467a11118d62c79aa8fb5 Mon Sep 17 00:00:00 2001 From: Sebastian Stock <42280794+sostock@users.noreply.github.com> Date: Wed, 12 May 2021 14:47:50 +0200 Subject: [PATCH 001/135] Enable conversion of CompoundPeriod to Period --- stdlib/Dates/src/periods.jl | 3 +++ stdlib/Dates/test/periods.jl | 13 +++++++++++++ 2 files changed, 16 insertions(+) diff --git a/stdlib/Dates/src/periods.jl b/stdlib/Dates/src/periods.jl index 22c792cb2f333f..61df01302521b7 100644 --- a/stdlib/Dates/src/periods.jl +++ b/stdlib/Dates/src/periods.jl @@ -357,6 +357,9 @@ function Base.string(x::CompoundPeriod) end Base.show(io::IO,x::CompoundPeriod) = print(io, string(x)) +Base.convert(::Type{T}, x::CompoundPeriod) where T<:Period = + isconcretetype(T) ? sum(T, x.periods) : throw(MethodError(convert,(T,x))) + # E.g. Year(1) + Day(1) (+)(x::Period,y::Period) = CompoundPeriod(Period[x, y]) (+)(x::CompoundPeriod, y::Period) = CompoundPeriod(vcat(x.periods, y)) diff --git a/stdlib/Dates/test/periods.jl b/stdlib/Dates/test/periods.jl index 81aacd1a9e54b6..3bb310be4ee84a 100644 --- a/stdlib/Dates/test/periods.jl +++ b/stdlib/Dates/test/periods.jl @@ -519,5 +519,18 @@ end #Test combined Fixed and Other Periods @test (1m + 1d < 1m + 1s) == false end + +@testset "Convert CompoundPeriod to Period" begin + @test convert(Month, Year(1) + Month(1)) === Month(13) + @test convert(Second, Minute(1) + Second(30)) === Second(90) + @test convert(Minute, Minute(1) + Second(60)) === Minute(2) + @test convert(Millisecond, Minute(1) + Second(30)) === Millisecond(90_000) + @test_throws InexactError convert(Minute, Minute(1) + Second(30)) + @test_throws MethodError convert(Month, Minute(1) + Second(30)) + @test_throws MethodError convert(Second, Month(1) + Second(30)) + @test_throws MethodError convert(Period, Minute(1) + Second(30)) + @test_throws MethodError convert(Dates.FixedPeriod, Minute(1) + Second(30)) +end + end From 6e859785cb0e4fa8b0ffb2b3bff13605a7a67a81 Mon Sep 17 00:00:00 2001 From: chriselrod Date: Fri, 11 Jun 2021 11:38:07 -0400 Subject: [PATCH 002/135] @propagate_inbounds on (get/set)index! for SharedArray --- stdlib/SharedArrays/src/SharedArrays.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stdlib/SharedArrays/src/SharedArrays.jl b/stdlib/SharedArrays/src/SharedArrays.jl index 85f1eb4fff1500..1348a68dca9571 100644 --- a/stdlib/SharedArrays/src/SharedArrays.jl +++ b/stdlib/SharedArrays/src/SharedArrays.jl @@ -507,9 +507,9 @@ end Array(S::SharedArray) = S.s # pass through getindex and setindex! - unlike DArrays, these always work on the complete array -getindex(S::SharedArray, i::Real) = getindex(S.s, i) +Base.@propagate_inbounds getindex(S::SharedArray, i::Real) = getindex(S.s, i) -setindex!(S::SharedArray, x, i::Real) = setindex!(S.s, x, i) +Base.@propagate_inbounds setindex!(S::SharedArray, x, i::Real) = setindex!(S.s, x, i) function fill!(S::SharedArray, v) vT = convert(eltype(S), v) From 860f99433210b2cc4b7ac8e9c4f4bfa1f9cdcf6d Mon Sep 17 00:00:00 2001 From: Sukera Date: Tue, 20 Jul 2021 09:49:43 +0200 Subject: [PATCH 003/135] Add isinf/isnan check for %g/%G formatting --- stdlib/Printf/src/Printf.jl | 42 ++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/stdlib/Printf/src/Printf.jl b/stdlib/Printf/src/Printf.jl index 9226d2c7fa5c66..8dacee5a1dc1b3 100644 --- a/stdlib/Printf/src/Printf.jl +++ b/stdlib/Printf/src/Printf.jl @@ -424,27 +424,31 @@ const __BIG_FLOAT_MAX__ = 8192 elseif T == Val{'f'} || T == Val{'F'} newpos = Ryu.writefixed(buf, pos, x, prec, plus, space, hash, UInt8('.')) elseif T == Val{'g'} || T == Val{'G'} - # C11-compliant general format - prec = prec == 0 ? 1 : prec - # format the value in scientific notation and parse the exponent part - exp = let p = Ryu.writeexp(buf, pos, x, prec) - b1, b2, b3, b4 = buf[p-4], buf[p-3], buf[p-2], buf[p-1] - Z = UInt8('0') - if b1 == UInt8('e') - # two-digit exponent - sign = b2 == UInt8('+') ? 1 : -1 - exp = 10 * (b3 - Z) + (b4 - Z) + if isinf(x) || isnan(x) + newpos = Ryu.writeshortest(buf, pos, x, plus, space) + else + # C11-compliant general format + prec = prec == 0 ? 1 : prec + # format the value in scientific notation and parse the exponent part + exp = let p = Ryu.writeexp(buf, pos, x, prec) + b1, b2, b3, b4 = buf[p-4], buf[p-3], buf[p-2], buf[p-1] + Z = UInt8('0') + if b1 == UInt8('e') + # two-digit exponent + sign = b2 == UInt8('+') ? 1 : -1 + exp = 10 * (b3 - Z) + (b4 - Z) + else + # three-digit exponent + sign = b1 == UInt8('+') ? 1 : -1 + exp = 100 * (b2 - Z) + 10 * (b3 - Z) + (b4 - Z) + end + flipsign(exp, sign) + end + if -4 ≤ exp < prec + newpos = Ryu.writefixed(buf, pos, x, prec - (exp + 1), plus, space, hash, UInt8('.'), !hash) else - # three-digit exponent - sign = b1 == UInt8('+') ? 1 : -1 - exp = 100 * (b2 - Z) + 10 * (b3 - Z) + (b4 - Z) + newpos = Ryu.writeexp(buf, pos, x, prec - 1, plus, space, hash, T == Val{'g'} ? UInt8('e') : UInt8('E'), UInt8('.'), !hash) end - flipsign(exp, sign) - end - if -4 ≤ exp < prec - newpos = Ryu.writefixed(buf, pos, x, prec - (exp + 1), plus, space, hash, UInt8('.'), !hash) - else - newpos = Ryu.writeexp(buf, pos, x, prec - 1, plus, space, hash, T == Val{'g'} ? UInt8('e') : UInt8('E'), UInt8('.'), !hash) end elseif T == Val{'a'} || T == Val{'A'} x, neg = x < 0 || x === -Base.zero(x) ? (-x, true) : (x, false) From 6a7c78b8a5ed0423fde478268bda42b4ff62f3ff Mon Sep 17 00:00:00 2001 From: Sukera Date: Tue, 20 Jul 2021 09:54:39 +0200 Subject: [PATCH 004/135] Add test for Inf/NaN handling in %g/%G Printf --- stdlib/Printf/test/runtests.jl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/stdlib/Printf/test/runtests.jl b/stdlib/Printf/test/runtests.jl index 30524d600cdf83..3d7929c42e9e05 100644 --- a/stdlib/Printf/test/runtests.jl +++ b/stdlib/Printf/test/runtests.jl @@ -94,6 +94,15 @@ end @test Printf.@sprintf("%g", 123456.7) == "123457" @test Printf.@sprintf("%g", 1234567.8) == "1.23457e+06" + # %g regression gh #41631 + for (val, res) in ((Inf, "Inf"), + (-Inf, "-Inf"), + (NaN, "NaN"), + (-NaN, "NaN")) + @test Printf.@sprintf("%g", val) == res + @test Printf.@sprintf("%G", val) == res + end + # zeros @test Printf.@sprintf("%.15g", 0) == "0" @test Printf.@sprintf("%#.15g", 0) == "0.00000000000000" From 4c3829d413a12c2b4a87952e0f6d1ecbbff63239 Mon Sep 17 00:00:00 2001 From: Kenta Sato Date: Mon, 2 Aug 2021 17:30:24 +0900 Subject: [PATCH 005/135] guard `isempty (close #41656) (#41752) --- 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 b5ded199688ee8..278dda28125594 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 e765dc9279b86d..411135ac633138 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 6f296906d8443ba83742e6050de78389d38bfdd7 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Mon, 2 Aug 2021 22:43:23 +0900 Subject: [PATCH 006/135] make sure to use `io` passed to `UndefVarError_hint` (#41757) --- stdlib/REPL/src/REPLCompletions.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stdlib/REPL/src/REPLCompletions.jl b/stdlib/REPL/src/REPLCompletions.jl index 44b3e6a3a4158e..6c0a7b0a871869 100644 --- a/stdlib/REPL/src/REPLCompletions.jl +++ b/stdlib/REPL/src/REPLCompletions.jl @@ -828,9 +828,9 @@ end function UndefVarError_hint(io::IO, ex::UndefVarError) var = ex.var if var === :or - print("\nsuggestion: Use `||` for short-circuiting boolean OR.") + print(io, "\nsuggestion: Use `||` for short-circuiting boolean OR.") elseif var === :and - print("\nsuggestion: Use `&&` for short-circuiting boolean AND.") + print(io, "\nsuggestion: Use `&&` for short-circuiting boolean AND.") end end From 4bcdf9dfff7c5b8409d55c4ecfef70d5cd4b789e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C4=81K=C4=83?= Date: Mon, 2 Aug 2021 23:23:28 +0800 Subject: [PATCH 007/135] Small documentation enhancement and typo fix (#41758) --- doc/src/manual/arrays.md | 2 +- doc/src/manual/style-guide.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/src/manual/arrays.md b/doc/src/manual/arrays.md index dcdc853ede1253..ac4b4d2e61e87d 100644 --- a/doc/src/manual/arrays.md +++ b/doc/src/manual/arrays.md @@ -875,7 +875,7 @@ full set of cartesian indices to do their lookup (see [`IndexStyle`](@ref) to introspect which is which). As such, when iterating over an entire array, it's much better to iterate over [`eachindex(A)`](@ref) instead of `1:length(A)`. Not only will the former be much faster in cases where `A` is `IndexCartesian`, -but it will also support OffsetArrays, too. +but it will also support [OffsetArrays](https://github.com/JuliaArrays/OffsetArrays.jl), too. #### Omitted and extra indices diff --git a/doc/src/manual/style-guide.md b/doc/src/manual/style-guide.md index 3a94f263e9e652..5201152ce31a45 100644 --- a/doc/src/manual/style-guide.md +++ b/doc/src/manual/style-guide.md @@ -144,7 +144,7 @@ is stated to be the API. This has several benefits: - Package developers are freer to change the implementation without breaking user code. - Methods can be passed to higher-order constructs like [`map`](@ref) (e.g. - `map(imag, zs))` rather than `[z.im for z in zs]`). + `map(imag, zs)`) rather than `[z.im for z in zs]`). - Methods can be defined on abstract types. - Methods can describe a conceptual operation that can be shared across disparate types (e.g. `real(z)` works on Complex numbers or Quaternions). From ed13d0959cb714549b6838388f016363eb147c30 Mon Sep 17 00:00:00 2001 From: Nathan Daly Date: Mon, 2 Aug 2021 12:49:39 -0400 Subject: [PATCH 008/135] Shuffle profile round robin thread order before taking every sample (#41732) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Uses O(n) "modern Fisher–Yates shuffle" - https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm Add C buffer to store order for sampling threads in Profile, which is shuffled on every sample. --- src/signal-handling.c | 26 ++++++++++++++++++++++++++ src/signals-mach.c | 6 ++++-- src/signals-unix.c | 5 ++++- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/signal-handling.c b/src/signal-handling.c index 8011c62934d289..23fa69f6e4475d 100644 --- a/src/signal-handling.c +++ b/src/signal-handling.c @@ -25,11 +25,15 @@ static volatile size_t bt_size_cur = 0; static volatile uint64_t nsecprof = 0; static volatile int running = 0; static const uint64_t GIGA = 1000000000ULL; +static uint64_t profile_cong_rng_seed = 0; +static uint64_t profile_cong_rng_unbias = 0; +static volatile uint64_t *profile_round_robin_thread_order = NULL; // Timers to take samples at intervals JL_DLLEXPORT void jl_profile_stop_timer(void); JL_DLLEXPORT int jl_profile_start_timer(void); void jl_lock_profile(void); void jl_unlock_profile(void); +void jl_shuffle_int_array_inplace(volatile uint64_t *carray, size_t size, uint64_t *seed); JL_DLLEXPORT int jl_profile_is_buffer_full(void) { @@ -288,6 +292,17 @@ JL_DLLEXPORT int jl_profile_init(size_t maxsize, uint64_t delay_nsec) nsecprof = delay_nsec; if (bt_data_prof != NULL) free((void*)bt_data_prof); + if (profile_round_robin_thread_order == NULL) { + // NOTE: We currently only allocate this once, since jl_n_threads cannot change + // during execution of a julia process. If/when this invariant changes in the + // future, this will have to be adjusted. + profile_round_robin_thread_order = (uint64_t*) calloc(jl_n_threads, sizeof(uint64_t)); + for (int i = 0; i < jl_n_threads; i++) { + profile_round_robin_thread_order[i] = i; + } + } + seed_cong(&profile_cong_rng_seed); + unbias_cong(jl_n_threads, &profile_cong_rng_unbias); bt_data_prof = (jl_bt_element_t*) calloc(maxsize, sizeof(jl_bt_element_t)); if (bt_data_prof == NULL && maxsize > 0) return -1; @@ -295,6 +310,17 @@ JL_DLLEXPORT int jl_profile_init(size_t maxsize, uint64_t delay_nsec) return 0; } +void jl_shuffle_int_array_inplace(volatile uint64_t *carray, size_t size, uint64_t *seed) { + // The "modern Fisher–Yates shuffle" - O(n) algorithm + // https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm + for (size_t i = size - 1; i >= 1; --i) { + size_t j = cong(i, profile_cong_rng_unbias, seed); + uint64_t tmp = carray[j]; + carray[j] = carray[i]; + carray[i] = tmp; + } +} + JL_DLLEXPORT uint8_t *jl_profile_get_data(void) { return (uint8_t*) bt_data_prof; diff --git a/src/signals-mach.c b/src/signals-mach.c index 3f133c3189b105..7a678af4ec65fd 100644 --- a/src/signals-mach.c +++ b/src/signals-mach.c @@ -524,7 +524,6 @@ static kern_return_t profiler_segv_handler void *mach_profile_listener(void *arg) { (void)arg; - int i; const int max_size = 512; attach_exception_port(mach_thread_self(), 1); #ifdef LLVMLIBUNWIND @@ -541,7 +540,10 @@ void *mach_profile_listener(void *arg) jl_lock_profile(); void *unused = NULL; int keymgr_locked = _keymgr_get_and_lock_processwide_ptr_2(KEYMGR_GCC3_DW2_OBJ_LIST, &unused) == 0; - for (i = jl_n_threads; i-- > 0; ) { + jl_shuffle_int_array_inplace(profile_round_robin_thread_order, jl_n_threads, &profile_cong_rng_seed); + for (int idx = jl_n_threads; idx-- > 0; ) { + // Stop the threads in the random round-robin order. + int i = profile_round_robin_thread_order[idx]; // if there is no space left, break early if (jl_profile_is_buffer_full()) { jl_profile_stop_timer(); diff --git a/src/signals-unix.c b/src/signals-unix.c index bb19e2bd65d785..ecfa144d68d99e 100644 --- a/src/signals-unix.c +++ b/src/signals-unix.c @@ -745,7 +745,10 @@ static void *signal_listener(void *arg) // (so that thread zero gets notified last) if (critical || profile) jl_lock_profile(); - for (int i = jl_n_threads; i-- > 0; ) { + jl_shuffle_int_array_inplace(profile_round_robin_thread_order, jl_n_threads, &profile_cong_rng_seed); + for (int idx = jl_n_threads; idx-- > 0; ) { + // Stop the threads in the random round-robin order. + int i = profile_round_robin_thread_order[idx]; // notify thread to stop jl_thread_suspend_and_get_state(i, &signal_context); From f711f0a9076b9f11f9034985086d73bc285c2ca6 Mon Sep 17 00:00:00 2001 From: Nathan Daly Date: Mon, 2 Aug 2021 12:51:50 -0400 Subject: [PATCH 009/135] [CONTRIBUTING.md] Add note that we prefer `squash+merge` when merging PRs. --- CONTRIBUTING.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 83d9bdd48f3a78..d294570483be4b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -287,6 +287,11 @@ runtest harness). - To remove whitespace relative to the `master` branch, run `git rebase --whitespace=fix master`. +#### Git Recommendations For Pull Request Reviewers + +- When merging, we generally like `squash+merge`. Unless it is the rare case of a PR with carefully staged individual commits that you want in the history separately, in which case `merge` is acceptable, but usually prefer `squash+merge`. + + ## Resources * Julia From 705f489f3fb70cbe891ac6b898a71f4abc3bb11e Mon Sep 17 00:00:00 2001 From: DilumAluthgeBot <43731525+DilumAluthgeBot@users.noreply.github.com> Date: Tue, 3 Aug 2021 12:12:45 +0000 Subject: [PATCH 010/135] =?UTF-8?q?=F0=9F=A4=96=20Bump=20the=20Pkg=20stdli?= =?UTF-8?q?b=20from=2039cc95a6=20to=205434d05f=20(#41766)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Pkg-39cc95a62eb4fddf27588b56d5cbd1a803ce9bda.tar.gz/md5 | 1 - .../Pkg-39cc95a62eb4fddf27588b56d5cbd1a803ce9bda.tar.gz/sha512 | 1 - .../Pkg-5434d05fba65f4ad735a85644af3c9fa16a1d75c.tar.gz/md5 | 1 + .../Pkg-5434d05fba65f4ad735a85644af3c9fa16a1d75c.tar.gz/sha512 | 1 + stdlib/Pkg.version | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 deps/checksums/Pkg-39cc95a62eb4fddf27588b56d5cbd1a803ce9bda.tar.gz/md5 delete mode 100644 deps/checksums/Pkg-39cc95a62eb4fddf27588b56d5cbd1a803ce9bda.tar.gz/sha512 create mode 100644 deps/checksums/Pkg-5434d05fba65f4ad735a85644af3c9fa16a1d75c.tar.gz/md5 create mode 100644 deps/checksums/Pkg-5434d05fba65f4ad735a85644af3c9fa16a1d75c.tar.gz/sha512 diff --git a/deps/checksums/Pkg-39cc95a62eb4fddf27588b56d5cbd1a803ce9bda.tar.gz/md5 b/deps/checksums/Pkg-39cc95a62eb4fddf27588b56d5cbd1a803ce9bda.tar.gz/md5 deleted file mode 100644 index d44a1fc542d8e0..00000000000000 --- a/deps/checksums/Pkg-39cc95a62eb4fddf27588b56d5cbd1a803ce9bda.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -00b52de986fa6a9d8c8ec4b7fd7ad5c2 diff --git a/deps/checksums/Pkg-39cc95a62eb4fddf27588b56d5cbd1a803ce9bda.tar.gz/sha512 b/deps/checksums/Pkg-39cc95a62eb4fddf27588b56d5cbd1a803ce9bda.tar.gz/sha512 deleted file mode 100644 index f67f716702e18f..00000000000000 --- a/deps/checksums/Pkg-39cc95a62eb4fddf27588b56d5cbd1a803ce9bda.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -c198c24dbb5cb66b83ffc9fdb5edb0b52df800b371eb5f95ed7db95e3586ff5aad7577c514f556f203479b0be7f6847390d99029a3bb358dcefc761ba3f6cd2b diff --git a/deps/checksums/Pkg-5434d05fba65f4ad735a85644af3c9fa16a1d75c.tar.gz/md5 b/deps/checksums/Pkg-5434d05fba65f4ad735a85644af3c9fa16a1d75c.tar.gz/md5 new file mode 100644 index 00000000000000..fe00ce3a5adaa6 --- /dev/null +++ b/deps/checksums/Pkg-5434d05fba65f4ad735a85644af3c9fa16a1d75c.tar.gz/md5 @@ -0,0 +1 @@ +76a298ceebe05a10d5f9740fc1648d6e diff --git a/deps/checksums/Pkg-5434d05fba65f4ad735a85644af3c9fa16a1d75c.tar.gz/sha512 b/deps/checksums/Pkg-5434d05fba65f4ad735a85644af3c9fa16a1d75c.tar.gz/sha512 new file mode 100644 index 00000000000000..c35c85dd7d4601 --- /dev/null +++ b/deps/checksums/Pkg-5434d05fba65f4ad735a85644af3c9fa16a1d75c.tar.gz/sha512 @@ -0,0 +1 @@ +6e5abec3dc08b39939b94ca8bd1e35e89e3254058cd0cdadc6e7ba4e872784dee363aa5fbf57d1981d4d2f49fea19bfe5a0f774ec869a96b36176e2bb3ab1b93 diff --git a/stdlib/Pkg.version b/stdlib/Pkg.version index 6b95e2b7033bd7..2b7ec72564ddcc 100644 --- a/stdlib/Pkg.version +++ b/stdlib/Pkg.version @@ -1,2 +1,2 @@ PKG_BRANCH = master -PKG_SHA1 = 39cc95a62eb4fddf27588b56d5cbd1a803ce9bda +PKG_SHA1 = 5434d05fba65f4ad735a85644af3c9fa16a1d75c From b686e71eff46a8ea898827bd8b2569931596a655 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Tue, 3 Aug 2021 17:24:37 +0200 Subject: [PATCH 011/135] [Timing Imports] Use atomic_add! and atomic_sub! (#41737) --- stdlib/InteractiveUtils/src/macros.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stdlib/InteractiveUtils/src/macros.jl b/stdlib/InteractiveUtils/src/macros.jl index 701f548e9da91d..cb7dbde1449069 100644 --- a/stdlib/InteractiveUtils/src/macros.jl +++ b/stdlib/InteractiveUtils/src/macros.jl @@ -235,10 +235,10 @@ end macro time_imports(ex) quote try - Base.TIMING_IMPORTS[] += 1 + Base.Threads.atomic_add!(Base.TIMING_IMPORTS, 1) $(esc(ex)) finally - Base.TIMING_IMPORTS[] -= 1 + Base.Threads.atomic_sub!(Base.TIMING_IMPORTS, 1) end end end From ca0331f75182eb221a8a80000edb7a758fcbb87b Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Tue, 3 Aug 2021 13:14:26 -0400 Subject: [PATCH 012/135] fix #40048, stack overflows in type intersection (#41687) --- src/subtype.c | 35 +++++++++++++++++++++-------------- test/subtype.jl | 13 +++++++++++++ 2 files changed, 34 insertions(+), 14 deletions(-) diff --git a/src/subtype.c b/src/subtype.c index 0d87532e73c396..158a9dd70b3f37 100644 --- a/src/subtype.c +++ b/src/subtype.c @@ -2210,13 +2210,29 @@ static int subtype_in_env_existential(jl_value_t *x, jl_value_t *y, jl_stenv_t * return issub; } +// See if var y is reachable from x via bounds; used to avoid cycles. +static int reachable_var(jl_value_t *x, jl_tvar_t *y, jl_stenv_t *e) +{ + if (in_union(x, (jl_value_t*)y)) + return 1; + if (!jl_is_typevar(x)) + return 0; + jl_varbinding_t *xv = lookup(e, (jl_tvar_t*)x); + if (xv == NULL) + return 0; + return reachable_var(xv->ub, y, e) || reachable_var(xv->lb, y, e); +} + static jl_value_t *intersect_var(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int8_t R, int param) { jl_varbinding_t *bb = lookup(e, b); if (bb == NULL) return R ? intersect_aside(a, b->ub, e, 1, 0) : intersect_aside(b->ub, a, e, 0, 0); - if (bb->lb == bb->ub && jl_is_typevar(bb->lb) && bb->lb != (jl_value_t*)b) + if (reachable_var(bb->lb, b, e) || reachable_var(bb->ub, b, e)) + return a; + if (bb->lb == bb->ub && jl_is_typevar(bb->lb)) { return intersect(a, bb->lb, e, param); + } if (!jl_is_type(a) && !jl_is_typevar(a)) return set_var_to_const(bb, a, NULL); int d = bb->depth0; @@ -2521,7 +2537,11 @@ static jl_value_t *intersect_unionall_(jl_value_t *t, jl_unionall_t *u, jl_stenv // if the var for this unionall (based on identity) already appears somewhere // in the environment, rename to get a fresh var. // TODO: might need to look inside types in btemp->lb and btemp->ub + int envsize = 0; while (btemp != NULL) { + envsize++; + if (envsize > 150) + return t; if (btemp->var == u->var || btemp->lb == (jl_value_t*)u->var || btemp->ub == (jl_value_t*)u->var) { u = rename_unionall(u); @@ -2923,19 +2943,6 @@ static int subtype_by_bounds(jl_value_t *x, jl_value_t *y, jl_stenv_t *e) return compareto_var(x, (jl_tvar_t*)y, e, -1) || compareto_var(y, (jl_tvar_t*)x, e, 1); } -// See if var y is reachable from x via bounds; used to avoid cycles. -static int reachable_var(jl_value_t *x, jl_tvar_t *y, jl_stenv_t *e) -{ - if (x == (jl_value_t*)y) - return 1; - if (!jl_is_typevar(x)) - return 0; - jl_varbinding_t *xv = lookup(e, (jl_tvar_t*)x); - if (xv == NULL) - return 0; - return reachable_var(xv->ub, y, e) || reachable_var(xv->lb, y, e); -} - // `param` means we are currently looking at a parameter of a type constructor // (as opposed to being outside any type constructor, or comparing variable bounds). // this is used to record the positions where type variables occur for the diff --git a/test/subtype.jl b/test/subtype.jl index 244ce3c4b79009..17d2b491003fec 100644 --- a/test/subtype.jl +++ b/test/subtype.jl @@ -1914,3 +1914,16 @@ end f18985(x::T, y...) where {T<:Union{Int32,Int64}} = (length(y), f18985(y[1], y[2:end]...)...) f18985(x::T) where {T<:Union{Int32,Int64}} = 100 @test f18985(1, 2, 3) == (2, 1, 100) + +# issue #40048 +let A = Tuple{Ref{T}, Vararg{T}} where T, + B = Tuple{Ref{U}, Union{Ref{S}, Ref{U}, Int}, Union{Ref{S}, S}} where S where U, + C = Tuple{Ref{U}, Union{Ref{S}, Ref{U}, Ref{W}}, Union{Ref{S}, W, V}} where V<:AbstractArray where W where S where U + I = typeintersect(A, B) + @test I != Union{} + @test I <: A + @test I <: B + # avoid stack overflow + J = typeintersect(A, C) + @test_broken J != Union{} +end From 81c29b2b318142f95b12482793e0a7303c8a58ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my?= Date: Tue, 3 Aug 2021 15:18:08 -0400 Subject: [PATCH 013/135] Add `canonicalize` to Dates docs Also add a simple paragraph for `CompoundPeriod` and show an example of `canonicalize` in the text. --- stdlib/Dates/docs/src/index.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/stdlib/Dates/docs/src/index.md b/stdlib/Dates/docs/src/index.md index b8fdad56dc78c9..4975f175bbf16a 100644 --- a/stdlib/Dates/docs/src/index.md +++ b/stdlib/Dates/docs/src/index.md @@ -579,6 +579,26 @@ julia> Dates.value(Dates.Millisecond(10)) 10 ``` +Representing periods or durations that are not integer multiples of the basic types can be achieved +with the [`Dates.CompoundPeriod`](@ref) type. Compound periods may be constructed manually from simple +[`Period`](@ref) types. Additionally, the [`canonicalize`](@ref) function can be used to break down a +period into a [`Dates.CompoundPeriod`](@ref). This is particularly useful to convert a duration, e.g., +a difference of two `DateTime`, into a more convenient representation. + +```jldoctest +julia> cp = Dates.CompoundPeriod(Day(1),Minute(1)) +1 day, 1 minute + +julia> t1 = DateTime(2018,8,8,16,58,00) +2018-08-08T16:58:00 + +julia> t2 = DateTime(2021,6,23,10,00,00) +2021-06-23T10:00:00 + +julia> canonicalize(t2-t1) # creates a CompoundPeriod +149 weeks, 6 days, 17 hours, 2 minutes +``` + ## Rounding [`Date`](@ref) and [`DateTime`](@ref) values can be rounded to a specified resolution (e.g., 1 @@ -784,6 +804,7 @@ Dates.toprev(::Function, ::Dates.TimeType) ```@docs Dates.Period(::Any) Dates.CompoundPeriod(::Vector{<:Dates.Period}) +Dates.canonicalize Dates.value Dates.default Dates.periods From a27b844feb5563d73db12f7f55bc506541e0b37c Mon Sep 17 00:00:00 2001 From: William John Holden <10909243+wjholden@users.noreply.github.com> Date: Wed, 4 Aug 2021 00:08:00 +0200 Subject: [PATCH 014/135] Update networking-and-streams.md (#41486) Added a section at the end showing examples of IPv4/IPv6 UDP multicast. See https://github.com/JuliaLang/julia/issues/39208. Co-authored-by: Jameson Nash --- doc/src/manual/networking-and-streams.md | 65 ++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/doc/src/manual/networking-and-streams.md b/doc/src/manual/networking-and-streams.md index 0bdef1b338925b..fc62632433850c 100644 --- a/doc/src/manual/networking-and-streams.md +++ b/doc/src/manual/networking-and-streams.md @@ -351,3 +351,68 @@ Finished connection to google.com Finished connection to julialang.org Finished connection to github.com ``` + +## Multicast + +Julia supports [multicast](https://datatracker.ietf.org/doc/html/rfc1112) over IPv4 and IPv6 using the User Datagram Protocol ([UDP](https://datatracker.ietf.org/doc/html/rfc768)) as transport. + +Unlike the Transmission Control Protocol ([TCP](https://datatracker.ietf.org/doc/html/rfc793)), UDP makes almost no assumptions about the needs of the application. +TCP provides flow control (it accelerates and decelerates to maximize throughput), reliability (lost or corrupt packets are automatically retransmitted), sequencing (packets are ordered by the operating system before they are given to the application), segment size, and session setup and teardown. +UDP provides no such features. + +A common use for UDP is in multicast applications. +TCP is a stateful protocol for communication between exactly two devices. +UDP can use special multicast addresses to allow simultaneous communication between many devices. + +### Receiving IP Multicast Packets + +To transmit data over UDP multicast, simply `recv` on the socket, and the first packet received will be returned. Note that it may not be the first packet that you sent however! + +``` +using Sockets +group = ip"228.5.6.7" +socket = Sockets.UDPSocket() +bind(socket, ip"0.0.0.0", 6789) +join_multicast_group(socket, group) +println(String(recv(socket))) +leave_multicast_group(socket, group) +close(socket) +``` + +### Sending IP Multicast Packets + +To transmit data over UDP multicast, simply `send` to the socket. +Notice that it is not necessary for a sender to join the multicast group. + +``` +using Sockets +group = ip"228.5.6.7" +socket = Sockets.UDPSocket() +send(socket, group, 6789, "Hello over IPv4") +close(socket) +``` + +### IPv6 Example + +This example gives the same functionality as the previous program, but uses IPv6 as the network-layer protocol. + +Listener: +``` +using Sockets +group = Sockets.IPv6("ff05::5:6:7") +socket = Sockets.UDPSocket() +bind(socket, Sockets.IPv6("::"), 6789) +join_multicast_group(socket, group) +println(String(recv(socket))) +leave_multicast_group(socket, group) +close(socket) +``` + +Sender: +``` +using Sockets +group = Sockets.IPv6("ff05::5:6:7") +socket = Sockets.UDPSocket() +send(socket, group, 6789, "Hello over IPv6") +close(socket) +``` From 68db4b79cd1c3b86026e324b127f093ab17c7f7d Mon Sep 17 00:00:00 2001 From: Elliot Saba Date: Tue, 3 Aug 2021 18:10:02 -0700 Subject: [PATCH 015/135] [Sockets] Embed note warning about broken DNS configuration (#41734) Default Ubuntu installations contain a faulty DNS configuration that returns `EAI_AGAIN` instead of `EAI_NONAME`. To fix this, it appears that installing `libnss-resolve` works to fix the tests, so suggest that if we're on Linux and this test is noticed to be failing. Co-authored-by: Elliot Saba --- stdlib/Sockets/test/runtests.jl | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/stdlib/Sockets/test/runtests.jl b/stdlib/Sockets/test/runtests.jl index 552ca3eac528ee..328ea929f4b4ba 100644 --- a/stdlib/Sockets/test/runtests.jl +++ b/stdlib/Sockets/test/runtests.jl @@ -196,6 +196,31 @@ end @testset "getnameinfo on some unroutable IP addresses (RFC 5737)" begin + try + getnameinfo(ip"192.0.2.1") + getnameinfo(ip"198.51.100.1") + getnameinfo(ip"203.0.113.1") + getnameinfo(ip"0.1.1.1") + getnameinfo(ip"::ffff:0.1.1.1") + getnameinfo(ip"::ffff:192.0.2.1") + getnameinfo(ip"2001:db8::1") + catch + # NOTE: Default Ubuntu installations contain a faulty DNS configuration + # that returns `EAI_AGAIN` instead of `EAI_NONAME`. To fix this, try + # installing `libnss-resolve`, which installs the `systemd-resolve` + # backend for NSS, which should fix it. + # + # If you are running tests inside Docker, you'll need to install + # `libnss-resolve` both outside Docker (i.e. on the host machine) and + # inside the Docker container. + if Sys.islinux() + error_msg = string( + "`getnameinfo` failed on an unroutable IP address. ", + "If your DNS setup seems to be working, try installing libnss-resolve", + ) + @error(error_msg) + end + end @test getnameinfo(ip"192.0.2.1") == "192.0.2.1" @test getnameinfo(ip"198.51.100.1") == "198.51.100.1" @test getnameinfo(ip"203.0.113.1") == "203.0.113.1" From e57dc3d07eb31ea7431296c4a04ebfdf91415c3a Mon Sep 17 00:00:00 2001 From: Johnny Chen Date: Wed, 4 Aug 2021 21:42:40 +0800 Subject: [PATCH 016/135] string: improve error message for in -> occursin (#41783) --- base/strings/search.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/strings/search.jl b/base/strings/search.jl index 0a08ef7f60c90a..938ed8d527d997 100644 --- a/base/strings/search.jl +++ b/base/strings/search.jl @@ -641,4 +641,4 @@ The returned function is of type `Base.Fix2{typeof(occursin)}`. """ occursin(haystack) = Base.Fix2(occursin, haystack) -in(::AbstractString, ::AbstractString) = error("use occursin(x, y) for string containment") +in(::AbstractString, ::AbstractString) = error("use occursin(needle, haystack) for string containment") From 5118a1babf9d2963f31e98e427cc99a969d5ca46 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Wed, 4 Aug 2021 11:37:00 -0400 Subject: [PATCH 017/135] Add missing makefile header link (#41773) Without this the file won't get rebuilt if the header changes, potentially causing ABI mismatches and crashes. --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index c61523a2bacf77..25e8d931d83c9a 100644 --- a/src/Makefile +++ b/src/Makefile @@ -261,7 +261,7 @@ $(BUILDDIR)/interpreter.o $(BUILDDIR)/interpreter.dbg.obj: $(SRCDIR)/builtin_pro $(BUILDDIR)/jitlayers.o $(BUILDDIR)/jitlayers.dbg.obj: $(SRCDIR)/jitlayers.h $(SRCDIR)/codegen_shared.h $(BUILDDIR)/jltypes.o $(BUILDDIR)/jltypes.dbg.obj: $(SRCDIR)/builtin_proto.h $(build_shlibdir)/libllvmcalltest.$(SHLIB_EXT): $(SRCDIR)/codegen_shared.h $(BUILDDIR)/julia_version.h -$(BUILDDIR)/llvm-alloc-opt.o $(BUILDDIR)/llvm-alloc-opt.dbg.obj: $(SRCDIR)/codegen_shared.h +$(BUILDDIR)/llvm-alloc-opt.o $(BUILDDIR)/llvm-alloc-opt.dbg.obj: $(SRCDIR)/codegen_shared.h $(SRCDIR)/llvm-pass-helpers.h $(BUILDDIR)/llvm-final-gc-lowering.o $(BUILDDIR)/llvm-final-gc-lowering.dbg.obj: $(SRCDIR)/llvm-pass-helpers.h $(BUILDDIR)/llvm-gc-invariant-verifier.o $(BUILDDIR)/llvm-gc-invariant-verifier.dbg.obj: $(SRCDIR)/codegen_shared.h $(BUILDDIR)/llvm-late-gc-lowering.o $(BUILDDIR)/llvm-late-gc-lowering.dbg.obj: $(SRCDIR)/llvm-pass-helpers.h From d18d8a40497f65118681c3b2bef0a6ae3725d1dc Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Fri, 6 Aug 2021 02:12:17 +0900 Subject: [PATCH 018/135] compiler: speed up bootstrapping time by 25% (#41794) The optimizer code is full of loop constructions and I found they're really better to not run in interpreter. With this PR, we create the caches of the optimizer code first and it speeds up the succeeding bootstrapping to create the caches for the overall inference code. On my machine, the bootstrapping took about 80 seconds previously, but on this PR the time is reduced to about 60 seconds. --- base/compiler/bootstrap.jl | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/base/compiler/bootstrap.jl b/base/compiler/bootstrap.jl index f351429aff7eb7..f4adb47abf3d14 100644 --- a/base/compiler/bootstrap.jl +++ b/base/compiler/bootstrap.jl @@ -5,10 +5,20 @@ # especially try to make sure any recursive and leaf functions have concrete signatures, # since we won't be able to specialize & infer them at runtime -let fs = Any[typeinf_ext, typeinf, typeinf_edge, pure_eval_call, run_passes], - world = get_world_counter(), +time() = ccall(:jl_clock_now, Float64, ()) + +let + world = get_world_counter() interp = NativeInterpreter(world) + fs = Any[ + # we first create caches for the optimizer, because they contain many loop constructions + # and they're better to not run in interpreter even during bootstrapping + run_passes, + # then we create caches for inference entries + typeinf_ext, typeinf, typeinf_edge, + ] + # tfuncs can't be inferred from the inference entries above, so here we infer them manually for x in T_FFUNC_VAL push!(fs, x[3]) end @@ -20,6 +30,7 @@ let fs = Any[typeinf_ext, typeinf, typeinf_edge, pure_eval_call, run_passes], println(stderr, "WARNING: tfunc missing for ", reinterpret(IntrinsicFunction, Int32(i))) end end + starttime = time() for f in fs for m in _methods_by_ftype(Tuple{typeof(f), Vararg{Any}}, 10, typemax(UInt)) # remove any TypeVars from the intersection @@ -32,4 +43,6 @@ let fs = Any[typeinf_ext, typeinf, typeinf_edge, pure_eval_call, run_passes], typeinf_type(interp, m.method, Tuple{typ...}, m.sparams) end end + endtime = time() + println("Core.Compiler ──── ", sub_float(endtime,starttime), " seconds") end From a86fe0f8376326ed058f4ce39a70bebf8b2dda5a Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Thu, 5 Aug 2021 21:05:54 -0400 Subject: [PATCH 019/135] fix `break` outside of loop in gc-debug (#41776) --- src/gc-debug.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gc-debug.c b/src/gc-debug.c index 3a0e4bf78598b7..ed09cff212ff80 100644 --- a/src/gc-debug.c +++ b/src/gc-debug.c @@ -315,7 +315,6 @@ static void gc_verify_tags_page(jl_gc_pagemeta_t *pg) char *cur_page = gc_page_data((char*)halfpages - 1); if (cur_page == data) { lim = (char*)halfpages - 1; - break; } } // compute the freelist_map From cb30aa7a089f4d5f1c9f834d96c3788f2e93ebcc Mon Sep 17 00:00:00 2001 From: Dilum Aluthge Date: Thu, 5 Aug 2021 23:11:54 -0400 Subject: [PATCH 020/135] CI (Buildkite): on the `platform_linux` jobs, after building Julia, make sure that the working directory is clean (#41796) --- .buildkite/pipelines/main/platforms/linux64.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.buildkite/pipelines/main/platforms/linux64.yml b/.buildkite/pipelines/main/platforms/linux64.yml index 1e88db1144b4c4..44b0ebe29f5570 100644 --- a/.buildkite/pipelines/main/platforms/linux64.yml +++ b/.buildkite/pipelines/main/platforms/linux64.yml @@ -35,6 +35,9 @@ steps: make release make install + echo "--- Make sure that the working directory is clean" + if [ -z "$(git status --short)" ]; then echo "INFO: The working directory is clean."; else echo "ERROR: The working directory is dirty."; echo "Output of git status:"; git status; exit 1; fi + echo "--- Print Julia version info" ./julia -e 'using InteractiveUtils; InteractiveUtils.versioninfo()' From 131b75b327557db49059aa20fc6404bc61b32148 Mon Sep 17 00:00:00 2001 From: Dilum Aluthge Date: Fri, 6 Aug 2021 22:11:27 -0400 Subject: [PATCH 021/135] CI: Disable Codecov commit statuses (#41812) --- .codecov.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .codecov.yml diff --git a/.codecov.yml b/.codecov.yml new file mode 100644 index 00000000000000..35cde5cd5e8543 --- /dev/null +++ b/.codecov.yml @@ -0,0 +1,4 @@ +coverage: + status: + project: off + patch: off From 6fce8d50da57631e33ffc316c57a99bf5597d765 Mon Sep 17 00:00:00 2001 From: Dilum Aluthge Date: Fri, 6 Aug 2021 22:46:50 -0400 Subject: [PATCH 022/135] CI (Buildbot): As soon as a PR is created or updated, create pending (yellow) commit statuses for all Buildbot jobs (#41811) --- .github/CODEOWNERS | 6 ++- .github/workflows/statuses.yml | 97 ++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/statuses.yml diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 6cab5b68b11e91..5fc00a73b47d2e 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,3 +1,5 @@ -CODEOWNERS @JuliaLang/github-actions -/.github/ @JuliaLang/github-actions +CODEOWNERS @JuliaLang/github-actions +/.github/ @JuliaLang/github-actions /.buildkite/ @JuliaLang/github-actions + +/.github/workflows/statuses.yml @DilumAluthge diff --git a/.github/workflows/statuses.yml b/.github/workflows/statuses.yml new file mode 100644 index 00000000000000..27422b4e69345d --- /dev/null +++ b/.github/workflows/statuses.yml @@ -0,0 +1,97 @@ +# Please ping @DilumAluthge when making any changes to this file. + +# This is just a short-term solution until we have migrated all of CI to Buildkite. +# +# 1. TODO: delete this file once we have migrated all of CI to Buildkite. +# +# 2. TODO: disable GitHub Actions on the `JuliaLang/julia` repository once we have migrated all +# of CI to Buildkite. + +# Here are some steps that we take in this workflow file for security reasons: +# 1. We do not checkout any code. +# 2. We do not run any external actions. + +name: Statuses + +on: + push: + branches: + - 'master' + - 'release-*' + # When using the `pull_request_target` event, all PRs will get a `GITHUB_TOKEN` that has + # write permissions, even if the PR is from a fork. + # Therefore, for security reasons, we do not checkout any code in this workflow. + pull_request: + branches: + - 'master' + - 'release-*' + +# These are the permissions for the `GITHUB_TOKEN` token. +# We should only give the token the minimum necessary set of permissions. +permissions: + statuses: write + actions: none + checks: none + contents: none + deployments: none + issues: none + discussions: none + packages: none + pull-requests: none + repository-projects: none + security-events: none + +jobs: + statuses: + name: statuses + runs-on: ubuntu-latest + if: github.repository == 'JuliaLang/julia' + strategy: + fail-fast: false + steps: + - run: echo "SHA=${{ github.event.pull_request.head.sha }}" >> $GITHUB_ENV + if: github.event_name == 'pull_request' + + - run: echo "SHA=${{ env.GITHUB_SHA }}" >> $GITHUB_ENV + if: github.event_name != 'pull_request' + + - run: echo "The SHA is ${{ env.SHA }}" + + # As we incrementally migrate individual jobs from Buildbot to Buildkite, we should + # remove them from the `context_list`. + - run: | + declare -a CONTEXT_LIST=( + "buildbot/package_freebsd64" + "buildbot/package_linux32" + "buildbot/package_linuxaarch64" + "buildbot/package_linuxarmv7l" + "buildbot/package_linuxppc64le" + "buildbot/package_macos64" + "buildbot/package_macosaarch64" + "buildbot/package_musl64" + "buildbot/package_win32" + "buildbot/package_win64" + "buildbot/tester_freebsd64" + "buildbot/tester_linux32" + "buildbot/tester_linux64" + "buildbot/tester_linuxaarch64" + "buildbot/tester_linuxarmv7l" + "buildbot/tester_linuxppc64le" + "buildbot/tester_macos64" + "buildbot/tester_macosaarch64" + "buildbot/tester_musl64" + "buildbot/tester_win32" + "buildbot/tester_win64" + ) + for CONTEXT in "${CONTEXT_LIST[@]}" + do + curl \ + -X POST \ + -H "Authorization: token $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github.v3+json" \ + -d "{\"context\": \"$CONTEXT\", \"state\": \"$STATE\"}" \ + https://api.github.com/repos/JuliaLang/julia/statuses/${{ env.SHA }} + done + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + STATE: "pending" From d62e2060584cd8005fbd04661952dff0618a6920 Mon Sep 17 00:00:00 2001 From: Dilum Aluthge Date: Fri, 6 Aug 2021 23:10:19 -0400 Subject: [PATCH 023/135] CI (Buildbot): for the "Create Pending Statuses" GitHub Actions workflow, use the `pull_request_target` event instead of the `pull_request` event (#41814) --- .github/workflows/statuses.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/statuses.yml b/.github/workflows/statuses.yml index 27422b4e69345d..1c29288d4fe792 100644 --- a/.github/workflows/statuses.yml +++ b/.github/workflows/statuses.yml @@ -21,7 +21,7 @@ on: # When using the `pull_request_target` event, all PRs will get a `GITHUB_TOKEN` that has # write permissions, even if the PR is from a fork. # Therefore, for security reasons, we do not checkout any code in this workflow. - pull_request: + pull_request_target: branches: - 'master' - 'release-*' From ed866b5f0f36a245317d257d062bd000226bd18c Mon Sep 17 00:00:00 2001 From: Dilum Aluthge Date: Fri, 6 Aug 2021 23:41:42 -0400 Subject: [PATCH 024/135] CI (Buildbot): Fix a bug in the "Create Pending Statuses" GitHub Actions workflow (#41815) --- .github/workflows/statuses.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/statuses.yml b/.github/workflows/statuses.yml index 1c29288d4fe792..fa448e9d9fbf00 100644 --- a/.github/workflows/statuses.yml +++ b/.github/workflows/statuses.yml @@ -50,10 +50,10 @@ jobs: fail-fast: false steps: - run: echo "SHA=${{ github.event.pull_request.head.sha }}" >> $GITHUB_ENV - if: github.event_name == 'pull_request' + if: github.event_name == 'pull_request_target' - run: echo "SHA=${{ env.GITHUB_SHA }}" >> $GITHUB_ENV - if: github.event_name != 'pull_request' + if: github.event_name != 'pull_request_target' - run: echo "The SHA is ${{ env.SHA }}" From 0e8bb9596e29703e65d11214284e2fcac1b19bda Mon Sep 17 00:00:00 2001 From: Dilum Aluthge Date: Sat, 7 Aug 2021 00:39:27 -0400 Subject: [PATCH 025/135] CI (Buildbot): a simpler way of getting the SHA for the "Statuses" action (#41817) --- .github/workflows/statuses.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/statuses.yml b/.github/workflows/statuses.yml index fa448e9d9fbf00..26ec245d1ad181 100644 --- a/.github/workflows/statuses.yml +++ b/.github/workflows/statuses.yml @@ -52,7 +52,7 @@ jobs: - run: echo "SHA=${{ github.event.pull_request.head.sha }}" >> $GITHUB_ENV if: github.event_name == 'pull_request_target' - - run: echo "SHA=${{ env.GITHUB_SHA }}" >> $GITHUB_ENV + - run: echo "SHA=${{ github.sha }}" >> $GITHUB_ENV if: github.event_name != 'pull_request_target' - run: echo "The SHA is ${{ env.SHA }}" From 08fae511b9a616f40179f85f0d429b88fc5c815e Mon Sep 17 00:00:00 2001 From: Dilum Aluthge Date: Sat, 7 Aug 2021 20:55:55 -0400 Subject: [PATCH 026/135] CI (Buildbot, GHA): in the "Statuses" workflow, we only need to create pending (yellow) statuses for the `tester_` jobs (#41822) --- .github/workflows/statuses.yml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/.github/workflows/statuses.yml b/.github/workflows/statuses.yml index 26ec245d1ad181..ca358e6f79487a 100644 --- a/.github/workflows/statuses.yml +++ b/.github/workflows/statuses.yml @@ -61,16 +61,6 @@ jobs: # remove them from the `context_list`. - run: | declare -a CONTEXT_LIST=( - "buildbot/package_freebsd64" - "buildbot/package_linux32" - "buildbot/package_linuxaarch64" - "buildbot/package_linuxarmv7l" - "buildbot/package_linuxppc64le" - "buildbot/package_macos64" - "buildbot/package_macosaarch64" - "buildbot/package_musl64" - "buildbot/package_win32" - "buildbot/package_win64" "buildbot/tester_freebsd64" "buildbot/tester_linux32" "buildbot/tester_linux64" From bdd745722716693dc141545f7a83e59d1f13769c Mon Sep 17 00:00:00 2001 From: Dilum Aluthge Date: Sat, 7 Aug 2021 23:02:29 -0400 Subject: [PATCH 027/135] CI (Buildbot, GHA): in the "Statuses" workflow, remove the `macosaarch64` and `musl64` statuses (#41824) --- .github/workflows/statuses.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/statuses.yml b/.github/workflows/statuses.yml index ca358e6f79487a..a5e8161dd3b99b 100644 --- a/.github/workflows/statuses.yml +++ b/.github/workflows/statuses.yml @@ -68,8 +68,6 @@ jobs: "buildbot/tester_linuxarmv7l" "buildbot/tester_linuxppc64le" "buildbot/tester_macos64" - "buildbot/tester_macosaarch64" - "buildbot/tester_musl64" "buildbot/tester_win32" "buildbot/tester_win64" ) From ff4fe2861cf4552e5a46854de9b5f874353ced09 Mon Sep 17 00:00:00 2001 From: DilumAluthgeBot <43731525+DilumAluthgeBot@users.noreply.github.com> Date: Sun, 8 Aug 2021 19:55:46 +0000 Subject: [PATCH 028/135] =?UTF-8?q?=F0=9F=A4=96=20Bump=20the=20NetworkOpti?= =?UTF-8?q?ons=20stdlib=20from=206cea813=20to=2042a0b5f=20(#41804)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Dilum Aluthge --- .../md5 | 1 + .../sha512 | 1 + .../md5 | 1 - .../sha512 | 1 - stdlib/NetworkOptions.version | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 deps/checksums/NetworkOptions-42a0b5fcb7edb8ed5b0ae699f15ca6aedc0098ca.tar.gz/md5 create mode 100644 deps/checksums/NetworkOptions-42a0b5fcb7edb8ed5b0ae699f15ca6aedc0098ca.tar.gz/sha512 delete mode 100644 deps/checksums/NetworkOptions-6cea813ca841c400627b6cf4d4f4ec2599965ab6.tar.gz/md5 delete mode 100644 deps/checksums/NetworkOptions-6cea813ca841c400627b6cf4d4f4ec2599965ab6.tar.gz/sha512 diff --git a/deps/checksums/NetworkOptions-42a0b5fcb7edb8ed5b0ae699f15ca6aedc0098ca.tar.gz/md5 b/deps/checksums/NetworkOptions-42a0b5fcb7edb8ed5b0ae699f15ca6aedc0098ca.tar.gz/md5 new file mode 100644 index 00000000000000..f4cb70703e6e2c --- /dev/null +++ b/deps/checksums/NetworkOptions-42a0b5fcb7edb8ed5b0ae699f15ca6aedc0098ca.tar.gz/md5 @@ -0,0 +1 @@ +71511cd9b2192b86e23d39e58aca489b diff --git a/deps/checksums/NetworkOptions-42a0b5fcb7edb8ed5b0ae699f15ca6aedc0098ca.tar.gz/sha512 b/deps/checksums/NetworkOptions-42a0b5fcb7edb8ed5b0ae699f15ca6aedc0098ca.tar.gz/sha512 new file mode 100644 index 00000000000000..22a61934ed190a --- /dev/null +++ b/deps/checksums/NetworkOptions-42a0b5fcb7edb8ed5b0ae699f15ca6aedc0098ca.tar.gz/sha512 @@ -0,0 +1 @@ +fb70d3cb0c305929ab8223c5b16aa95cb17785da6c9b2f3dc0f8d34c26ddadd88abc7bb3e9ec53a2cdfeca2396fd698393b768a08b2692e6689327509d836620 diff --git a/deps/checksums/NetworkOptions-6cea813ca841c400627b6cf4d4f4ec2599965ab6.tar.gz/md5 b/deps/checksums/NetworkOptions-6cea813ca841c400627b6cf4d4f4ec2599965ab6.tar.gz/md5 deleted file mode 100644 index ab9875abdaa721..00000000000000 --- a/deps/checksums/NetworkOptions-6cea813ca841c400627b6cf4d4f4ec2599965ab6.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -6cfa681fc6a1c16d3dd3620c3b55d178 diff --git a/deps/checksums/NetworkOptions-6cea813ca841c400627b6cf4d4f4ec2599965ab6.tar.gz/sha512 b/deps/checksums/NetworkOptions-6cea813ca841c400627b6cf4d4f4ec2599965ab6.tar.gz/sha512 deleted file mode 100644 index 4d2e4a7acd6312..00000000000000 --- a/deps/checksums/NetworkOptions-6cea813ca841c400627b6cf4d4f4ec2599965ab6.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -4f0df64518b0d877462101c6cdc4c9311af74f72d5e266fd83ef320968fbf7b79a649f1e84ef1d3d8d13c41dfdd651e9164e95227896e01c423ac4f9c7e007cb diff --git a/stdlib/NetworkOptions.version b/stdlib/NetworkOptions.version index 0d398e16dafc17..6a9bf2182fc99a 100644 --- a/stdlib/NetworkOptions.version +++ b/stdlib/NetworkOptions.version @@ -1,2 +1,2 @@ NETWORKOPTIONS_BRANCH = master -NETWORKOPTIONS_SHA1 = 6cea813ca841c400627b6cf4d4f4ec2599965ab6 +NETWORKOPTIONS_SHA1 = 42a0b5fcb7edb8ed5b0ae699f15ca6aedc0098ca From 0d1e548d0a1fe9e0fcbe8c36caac2e344fc9a5fe Mon Sep 17 00:00:00 2001 From: Dilum Aluthge Date: Mon, 9 Aug 2021 00:35:47 -0400 Subject: [PATCH 029/135] CI (Buildbot, GHA): in the "Statuses" workflow, remove the `tester_linuxppc64le` status (#41831) --- .github/workflows/statuses.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/statuses.yml b/.github/workflows/statuses.yml index a5e8161dd3b99b..431b9fdfd89bf0 100644 --- a/.github/workflows/statuses.yml +++ b/.github/workflows/statuses.yml @@ -66,7 +66,6 @@ jobs: "buildbot/tester_linux64" "buildbot/tester_linuxaarch64" "buildbot/tester_linuxarmv7l" - "buildbot/tester_linuxppc64le" "buildbot/tester_macos64" "buildbot/tester_win32" "buildbot/tester_win64" From 9665d2a9248d7c7cb228a9ee0d9282041c337989 Mon Sep 17 00:00:00 2001 From: Dilum Aluthge Date: Mon, 9 Aug 2021 01:20:13 -0400 Subject: [PATCH 030/135] CI (Buildbot, GHA): In the "Statuses" workflow, remove the `tester_linuxarmv7l` status (#41832) --- .github/workflows/statuses.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/statuses.yml b/.github/workflows/statuses.yml index 431b9fdfd89bf0..0fcb8b37586e49 100644 --- a/.github/workflows/statuses.yml +++ b/.github/workflows/statuses.yml @@ -65,7 +65,6 @@ jobs: "buildbot/tester_linux32" "buildbot/tester_linux64" "buildbot/tester_linuxaarch64" - "buildbot/tester_linuxarmv7l" "buildbot/tester_macos64" "buildbot/tester_win32" "buildbot/tester_win64" From 7005b7d68be7e6dddb6fba70de855df0abdf3c22 Mon Sep 17 00:00:00 2001 From: Dilum Aluthge Date: Mon, 9 Aug 2021 03:57:21 -0400 Subject: [PATCH 031/135] CI (Buildbot, GHA): add a note about token permissions (#41825) --- .github/workflows/statuses.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/statuses.yml b/.github/workflows/statuses.yml index 0fcb8b37586e49..df86caa3acee30 100644 --- a/.github/workflows/statuses.yml +++ b/.github/workflows/statuses.yml @@ -10,6 +10,7 @@ # Here are some steps that we take in this workflow file for security reasons: # 1. We do not checkout any code. # 2. We do not run any external actions. +# 3. We only give `GITHUB_TOKEN` the minimum necessary set of permissions. name: Statuses From e87e30c0e33080ec746f72f8f2aeeb880c36c565 Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Mon, 9 Aug 2021 06:15:58 -0500 Subject: [PATCH 032/135] ?(x, y)TAB completes methods accepting x, y (#38791) * ?(x, y)TAB completes methods accepting x, y Closes #30052 xref #38704 xref #37993 Co-authored-by: Jameson Nash --- NEWS.md | 6 ++ stdlib/REPL/docs/src/index.md | 119 +++++++++++++++++++++++----- stdlib/REPL/src/LineEdit.jl | 16 ++++ stdlib/REPL/src/REPL.jl | 17 +++- stdlib/REPL/src/REPLCompletions.jl | 94 +++++++++++++++++++--- stdlib/REPL/test/replcompletions.jl | 30 +++++++ 6 files changed, 251 insertions(+), 31 deletions(-) diff --git a/NEWS.md b/NEWS.md index d64511283107dd..cb298402ea88d2 100644 --- a/NEWS.md +++ b/NEWS.md @@ -63,6 +63,12 @@ Standard library changes #### REPL +* ` ?(x, y` followed by TAB displays all methods that can be called + with arguments `x, y, ...`. (The space at the beginning prevents entering help-mode.) + `MyModule.?(x, y` limits the search to `MyModule`. TAB requires that at least one + argument have a type more specific than `Any`; use SHIFT-TAB instead of TAB + to allow any compatible methods. + #### SparseArrays #### Dates diff --git a/stdlib/REPL/docs/src/index.md b/stdlib/REPL/docs/src/index.md index 168d3e963b589b..ab4c4df19df5b6 100644 --- a/stdlib/REPL/docs/src/index.md +++ b/stdlib/REPL/docs/src/index.md @@ -307,6 +307,27 @@ Users should refer to `LineEdit.jl` to discover the available actions on key inp In both the Julian and help modes of the REPL, one can enter the first few characters of a function or type and then press the tab key to get a list all matches: +```julia-repl +julia> x[TAB] +julia> xor +``` + +In some cases it only completes part of the name, up to the next ambiguity: + +```julia-repl +julia> mapf[TAB] +julia> mapfold +``` + +If you hit tab again, then you get the list of things that might complete this: + +```julia-repl +julia> mapfold[TAB] +mapfoldl mapfoldr +``` + +Like other components of the REPL, the search is case-sensitive: + ```julia-repl julia> stri[TAB] stride strides string strip @@ -365,6 +386,46 @@ shell> /[TAB] .dockerinit bin/ dev/ home/ lib64/ mnt/ proc/ run/ srv/ tmp/ var/ ``` +Dictionary keys can also be tab completed: + +```julia-repl +julia> foo = Dict("qwer1"=>1, "qwer2"=>2, "asdf"=>3) +Dict{String,Int64} with 3 entries: + "qwer2" => 2 + "asdf" => 3 + "qwer1" => 1 + +julia> foo["q[TAB] + +"qwer1" "qwer2" +julia> foo["qwer +``` + +Tab completion can also help completing fields: + +```julia-repl +julia> x = 3 + 4im; + +julia> julia> x.[TAB][TAB] +im re + +julia> import UUIDs + +julia> UUIDs.uuid[TAB][TAB] +uuid1 uuid4 uuid5 uuid_version +``` + +Fields for output from functions can also be completed: + +```julia-repl +julia> split("","")[1].[TAB] +lastindex offset string +``` + +The completion of fields for output from functions uses type inference, and it can only suggest +fields if the function is type stable. + + Tab completion can help with investigation of the available methods matching the input arguments: ```julia-repl @@ -392,38 +453,54 @@ The completion of the methods uses type inference and can therefore see if the a even if the arguments are output from functions. The function needs to be type stable for the completion to be able to remove non-matching methods. -Tab completion can also help completing fields: +If you wonder which methods can be used with particular argument types, use `?` as the function name. +This shows an example of looking for functions in InteractiveUtils that accept a single string: ```julia-repl -julia> import UUIDs - -julia> UUIDs.uuid[TAB] -uuid1 uuid4 uuid_version +julia> InteractiveUtils.?("somefile")[TAB] +edit(path::AbstractString) in InteractiveUtils at InteractiveUtils/src/editless.jl:197 +less(file::AbstractString) in InteractiveUtils at InteractiveUtils/src/editless.jl:266 ``` -Fields for output from functions can also be completed: +This listed methods in the `InteractiveUtils` module that can be called on a string. +By default, this excludes methods where all arguments are typed as `Any`, +but you can see those too by holding down SHIFT-TAB instead of TAB: ```julia-repl -julia> split("","")[1].[TAB] -lastindex offset string +julia> InteractiveUtils.?("somefile")[SHIFT-TAB] +apropos(string) in REPL at REPL/src/docview.jl:796 +clipboard(x) in InteractiveUtils at InteractiveUtils/src/clipboard.jl:64 +code_llvm(f) in InteractiveUtils at InteractiveUtils/src/codeview.jl:221 +code_native(f) in InteractiveUtils at InteractiveUtils/src/codeview.jl:243 +edit(path::AbstractString) in InteractiveUtils at InteractiveUtils/src/editless.jl:197 +edit(f) in InteractiveUtils at InteractiveUtils/src/editless.jl:225 +eval(x) in InteractiveUtils at InteractiveUtils/src/InteractiveUtils.jl:3 +include(x) in InteractiveUtils at InteractiveUtils/src/InteractiveUtils.jl:3 +less(file::AbstractString) in InteractiveUtils at InteractiveUtils/src/editless.jl:266 +less(f) in InteractiveUtils at InteractiveUtils/src/editless.jl:274 +report_bug(kind) in InteractiveUtils at InteractiveUtils/src/InteractiveUtils.jl:391 +separate_kwargs(args...; kwargs...) in InteractiveUtils at InteractiveUtils/src/macros.jl:7 ``` -The completion of fields for output from functions uses type inference, and it can only suggest -fields if the function is type stable. +You can also use ` ?("somefile")[TAB]` and look across all modules, but the method lists can be long. -Dictionary keys can also be tab completed: +By omitting the closing parenthesis, you can include functions that might require additional arguments: ```julia-repl -julia> foo = Dict("qwer1"=>1, "qwer2"=>2, "asdf"=>3) -Dict{String,Int64} with 3 entries: - "qwer2" => 2 - "asdf" => 3 - "qwer1" => 1 - -julia> foo["q[TAB] - -"qwer1" "qwer2" -julia> foo["qwer +julia> using Mmap + +help?> Mmap.?("file",[TAB] +Mmap.Anonymous(name::String, readonly::Bool, create::Bool) in Mmap at Mmap/src/Mmap.jl:16 +mmap(file::AbstractString) in Mmap at Mmap/src/Mmap.jl:245 +mmap(file::AbstractString, ::Type{T}) where T<:Array in Mmap at Mmap/src/Mmap.jl:245 +mmap(file::AbstractString, ::Type{T}, dims::Tuple{Vararg{Integer, N}}) where {T<:Array, N} in Mmap at Mmap/src/Mmap.jl:245 +mmap(file::AbstractString, ::Type{T}, dims::Tuple{Vararg{Integer, N}}, offset::Integer; grow, shared) where {T<:Array, N} in Mmap at Mmap/src/Mmap.jl:245 +mmap(file::AbstractString, ::Type{T}, len::Integer) where T<:Array in Mmap at Mmap/src/Mmap.jl:251 +mmap(file::AbstractString, ::Type{T}, len::Integer, offset::Integer; grow, shared) where T<:Array in Mmap at Mmap/src/Mmap.jl:251 +mmap(file::AbstractString, ::Type{T}, dims::Tuple{Vararg{Integer, N}}) where {T<:BitArray, N} in Mmap at Mmap/src/Mmap.jl:316 +mmap(file::AbstractString, ::Type{T}, dims::Tuple{Vararg{Integer, N}}, offset::Integer; grow, shared) where {T<:BitArray, N} in Mmap at Mmap/src/Mmap.jl:316 +mmap(file::AbstractString, ::Type{T}, len::Integer) where T<:BitArray in Mmap at Mmap/src/Mmap.jl:322 +mmap(file::AbstractString, ::Type{T}, len::Integer, offset::Integer; grow, shared) where T<:BitArray in Mmap at Mmap/src/Mmap.jl:322 ``` ## Customizing Colors diff --git a/stdlib/REPL/src/LineEdit.jl b/stdlib/REPL/src/LineEdit.jl index 9a6160c960fe33..89f9a4cb992089 100644 --- a/stdlib/REPL/src/LineEdit.jl +++ b/stdlib/REPL/src/LineEdit.jl @@ -106,6 +106,11 @@ mutable struct PromptState <: ModeState refresh_wait::Union{Timer,Nothing} end +struct Modifiers + shift::Bool +end +Modifiers() = Modifiers(false) + options(s::PromptState) = if isdefined(s.p, :repl) && isdefined(s.p.repl, :options) # we can't test isa(s.p.repl, LineEditREPL) as LineEditREPL is defined @@ -1907,6 +1912,10 @@ mode(s::PromptState) = s.p # ::Prompt mode(s::SearchState) = @assert false mode(s::PrefixSearchState) = s.histprompt.parent_prompt # ::Prompt +setmodifiers!(s::MIState, m::Modifiers) = setmodifiers!(mode(s), m) +setmodifiers!(p::Prompt, m::Modifiers) = setmodifiers!(p.complete, m) +setmodifiers!(c) = nothing + # Search Mode completions function complete_line(s::SearchState, repeats) completions, partial, should_complete = complete_line(s.histprompt.complete, s) @@ -2174,6 +2183,11 @@ function edit_tab(s::MIState, jump_spaces::Bool=false, delete_trailing::Bool=jum return refresh_line(s) end +function shift_tab_completion(s::MIState) + setmodifiers!(s, Modifiers(true)) + return complete_line(s) +end + # return true iff the content of the buffer is modified # return false when only the position changed function edit_insert_tab(buf::IOBuffer, jump_spaces::Bool=false, delete_trailing::Bool=jump_spaces) @@ -2209,6 +2223,8 @@ const default_keymap = AnyDict( # Tab '\t' => (s::MIState,o...)->edit_tab(s, true), + # Shift-tab + "\e[Z" => (s::MIState,o...)->shift_tab_completion(s), # Enter '\r' => (s::MIState,o...)->begin if on_enter(s) || (eof(buffer(s)) && s.key_repeats > 1) diff --git a/stdlib/REPL/src/REPL.jl b/stdlib/REPL/src/REPL.jl index a661ffa218e97d..a815678b7ba521 100644 --- a/stdlib/REPL/src/REPL.jl +++ b/stdlib/REPL/src/REPL.jl @@ -55,6 +55,7 @@ import ..LineEdit: history_last, history_search, accept_result, + setmodifiers!, terminal, MIState, PromptState, @@ -470,16 +471,30 @@ LineEditREPL(t::TextTerminal, hascolor::Bool, envcolors::Bool=false) = false, false, false, envcolors ) -mutable struct REPLCompletionProvider <: CompletionProvider end +mutable struct REPLCompletionProvider <: CompletionProvider + modifiers::LineEdit.Modifiers +end +REPLCompletionProvider() = REPLCompletionProvider(LineEdit.Modifiers()) mutable struct ShellCompletionProvider <: CompletionProvider end struct LatexCompletions <: CompletionProvider end +setmodifiers!(c::REPLCompletionProvider, m::LineEdit.Modifiers) = c.modifiers = m + beforecursor(buf::IOBuffer) = String(buf.data[1:buf.ptr-1]) function complete_line(c::REPLCompletionProvider, s::PromptState) partial = beforecursor(s.input_buffer) full = LineEdit.input_string(s) ret, range, should_complete = completions(full, lastindex(partial)) + if !c.modifiers.shift + # Filter out methods where all arguments are `Any` + filter!(ret) do c + isa(c, REPLCompletions.MethodCompletion) || return true + sig = Base.unwrap_unionall(c.method.sig)::DataType + return !all(T -> T === Any || T === Vararg{Any}, sig.parameters[2:end]) + end + end + c.modifiers = LineEdit.Modifiers() return unique!(map(completion_text, ret)), partial[range], should_complete end diff --git a/stdlib/REPL/src/REPLCompletions.jl b/stdlib/REPL/src/REPLCompletions.jl index 6c0a7b0a871869..ba33c5f1593afd 100644 --- a/stdlib/REPL/src/REPLCompletions.jl +++ b/stdlib/REPL/src/REPLCompletions.jl @@ -478,17 +478,59 @@ function get_type(sym, fn::Module) return found ? Core.Typeof(val) : Any, found end +function get_type(T, found::Bool, default_any::Bool) + return found ? T : + default_any ? Any : throw(ArgumentError("argument not found")) +end + # Method completion on function call expression that look like :(max(1)) function complete_methods(ex_org::Expr, context_module::Module=Main) func, found = get_value(ex_org.args[1], context_module)::Tuple{Any,Bool} !found && return Completion[] - funargs = ex_org.args[2:end] - # handle broadcasting, but only handle number of arguments instead of - # argument types + args_ex, kwargs_ex = complete_methods_args(ex_org.args[2:end], ex_org, context_module, true, true) + + out = Completion[] + complete_methods!(out, func, args_ex, kwargs_ex) + return out +end + +function complete_any_methods(ex_org::Expr, callee_module::Module, context_module::Module, moreargs::Bool) + out = Completion[] + args_ex, kwargs_ex = try + complete_methods_args(ex_org.args[2:end], ex_org, context_module, false, false) + catch + return out + end + + for name in names(callee_module; all=true) + if !Base.isdeprecated(callee_module, name) && isdefined(callee_module, name) + func = getfield(callee_module, name) + if !isa(func, Module) + complete_methods!(out, func, args_ex, kwargs_ex, moreargs) + elseif callee_module === Main::Module && isa(func, Module) + callee_module2 = func + for name in names(callee_module2) + if isdefined(callee_module2, name) + func = getfield(callee_module, name) + if !isa(func, Module) + complete_methods!(out, func, args_ex, kwargs_ex, moreargs) + end + end + end + end + end + end + + return out +end + +function complete_methods_args(funargs::Vector{Any}, ex_org::Expr, context_module::Module, default_any::Bool, allow_broadcasting::Bool) args_ex = Any[] kwargs_ex = Pair{Symbol,Any}[] - if ex_org.head === :. && ex_org.args[2] isa Expr + if allow_broadcasting && ex_org.head === :. && ex_org.args[2] isa Expr + # handle broadcasting, but only handle number of arguments instead of + # argument types for _ in (ex_org.args[2]::Expr).args push!(args_ex, Any) end @@ -497,18 +539,20 @@ function complete_methods(ex_org::Expr, context_module::Module=Main) if isexpr(ex, :parameters) for x in ex.args n, v = isexpr(x, :kw) ? (x.args...,) : (x, x) - push!(kwargs_ex, n => first(get_type(v, context_module))) + push!(kwargs_ex, n => get_type(get_type(v, context_module)..., default_any)) end elseif isexpr(ex, :kw) n, v = (ex.args...,) - push!(kwargs_ex, n => first(get_type(v, context_module))) + push!(kwargs_ex, n => get_type(get_type(v, context_module)..., default_any)) else - push!(args_ex, first(get_type(ex, context_module))) + push!(args_ex, get_type(get_type(ex, context_module)..., default_any)) end end end + return args_ex, kwargs_ex +end - out = Completion[] +function complete_methods!(out::Vector{Completion}, @nospecialize(func), args_ex::Vector{Any}, kwargs_ex::Vector{Pair{Symbol,Any}}, moreargs::Bool=true) ml = methods(func) # Input types and number of arguments if isempty(kwargs_ex) @@ -525,6 +569,9 @@ function complete_methods(ex_org::Expr, context_module::Module=Main) ml = methods(kwfunc) func = kwfunc end + if !moreargs + na = typemax(Int) + end for (method::Method, orig_method) in zip(ml, orig_ml) ms = method.sig @@ -534,7 +581,6 @@ function complete_methods(ex_org::Expr, context_module::Module=Main) push!(out, MethodCompletion(func, t_in, method, orig_method)) end end - return out end include("latex_symbols.jl") @@ -652,6 +698,36 @@ function completions(string::String, pos::Int, context_module::Module=Main) partial = string[1:pos] inc_tag = Base.incomplete_tag(Meta.parse(partial, raise=false, depwarn=false)) + # ?(x, y)TAB lists methods you can call with these objects + # ?(x, y TAB lists methods that take these objects as the first two arguments + # MyModule.?(x, y)TAB restricts the search to names in MyModule + rexm = match(r"(\w+\.|)\?\((.*)$", partial) + if rexm !== nothing + # Get the module scope + if isempty(rexm.captures[1]) + callee_module = context_module + else + modname = Symbol(rexm.captures[1][1:end-1]) + if isdefined(context_module, modname) + callee_module = getfield(context_module, modname) + if !isa(callee_module, Module) + callee_module = context_module + end + else + callee_module = context_module + end + end + moreargs = !endswith(rexm.captures[2], ')') + callstr = "_(" * rexm.captures[2] + if moreargs + callstr *= ')' + end + ex_org = Meta.parse(callstr, raise=false, depwarn=false) + if isa(ex_org, Expr) + return complete_any_methods(ex_org, callee_module::Module, context_module, moreargs), (0:length(rexm.captures[1])+1) .+ rexm.offset, false + end + end + # if completing a key in a Dict identifier, partial_key, loc = dict_identifier_key(partial, inc_tag, context_module) if identifier !== nothing diff --git a/stdlib/REPL/test/replcompletions.jl b/stdlib/REPL/test/replcompletions.jl index 545e81a27968d3..14f6de445c0838 100644 --- a/stdlib/REPL/test/replcompletions.jl +++ b/stdlib/REPL/test/replcompletions.jl @@ -64,6 +64,8 @@ let ex = quote test6()=[a, a] test7() = rand(Bool) ? 1 : 1.0 test8() = Any[1][1] + test9(x::Char) = pass + test9(x::Char, i::Int) = pass kwtest(; x=1, y=2, w...) = pass kwtest2(a; x=1, y=2, w...) = pass @@ -516,6 +518,34 @@ for s in ("CompletionFoo.kwtest2(1; x=1,", @test occursin("a; x, y, w...", c[1]) end +################################################################# + +# method completion with `?` (arbitrary method with given argument types) +let s = "CompletionFoo.?([1,2,3], 2.0)" + c, r, res = test_complete(s) + @test !res + @test any(str->occursin("test(x::AbstractArray{T}, y) where T<:Real", str), c) + @test any(str->occursin("test(args...)", str), c) + @test !any(str->occursin("test3(x::AbstractArray{Int", str), c) + @test !any(str->occursin("test4", str), c) +end + +let s = "CompletionFoo.?('c')" + c, r, res = test_complete(s) + @test !res + @test any(str->occursin("test9(x::Char)", str), c) + @test !any(str->occursin("test9(x::Char, i::Int", str), c) +end + +let s = "CompletionFoo.?('c'" + c, r, res = test_complete(s) + @test !res + @test any(str->occursin("test9(x::Char)", str), c) + @test any(str->occursin("test9(x::Char, i::Int", str), c) +end + +################################################################# + # Test of inference based getfield completion let s = "(1+2im)." c,r = test_complete(s) From 702cf55497ca21274babc2708cd60535177bbb53 Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Mon, 9 Aug 2021 06:16:34 -0500 Subject: [PATCH 033/135] Revert "Add vim bindings to TerminalMenus (#37940)" This reverts commit 4a19b753804ed0b06fab9681309941862eaa7227. Closes #41799. --- stdlib/REPL/src/TerminalMenus/AbstractMenu.jl | 6 +++--- stdlib/REPL/test/TerminalMenus/runtests.jl | 20 ++++--------------- 2 files changed, 7 insertions(+), 19 deletions(-) diff --git a/stdlib/REPL/src/TerminalMenus/AbstractMenu.jl b/stdlib/REPL/src/TerminalMenus/AbstractMenu.jl index ee5bd4d4267955..f01df5c3893241 100644 --- a/stdlib/REPL/src/TerminalMenus/AbstractMenu.jl +++ b/stdlib/REPL/src/TerminalMenus/AbstractMenu.jl @@ -203,9 +203,9 @@ function request(term::REPL.Terminals.TTYTerminal, m::AbstractMenu; cursor::Unio lastoption = numoptions(m) c = readkey(term.in_stream) - if c == Int(ARROW_UP) || c == Int('k') + if c == Int(ARROW_UP) cursor[] = move_up!(m, cursor[], lastoption) - elseif c == Int(ARROW_DOWN) || c == Int('j') + elseif c == Int(ARROW_DOWN) cursor[] = move_down!(m, cursor[], lastoption) elseif c == Int(PAGE_UP) cursor[] = page_up!(m, cursor[], lastoption) @@ -217,7 +217,7 @@ function request(term::REPL.Terminals.TTYTerminal, m::AbstractMenu; cursor::Unio elseif c == Int(END_KEY) cursor[] = lastoption m.pageoffset = lastoption - m.pagesize - elseif c == 13 || c == Int(' ') # or + elseif c == 13 # # will break if pick returns true pick(m, cursor[]) && break elseif c == UInt32('q') diff --git a/stdlib/REPL/test/TerminalMenus/runtests.jl b/stdlib/REPL/test/TerminalMenus/runtests.jl index ac577dfd9ab272..62a91cc0a12562 100644 --- a/stdlib/REPL/test/TerminalMenus/runtests.jl +++ b/stdlib/REPL/test/TerminalMenus/runtests.jl @@ -6,22 +6,10 @@ using Test function simulate_input(expected, menu::TerminalMenus.AbstractMenu, keys...; kwargs...) - keydict = Dict(:up => "\e[A", - :down => "\e[B", - :enter => "\r") - vimdict = Dict(:up => "k", - :down => "j", - :enter => " ") - errs = [] - got = _simulate_input(keydict, deepcopy(menu), keys...; kwargs...) - got == expected || push!(errs, :arrows => got) - got = _simulate_input(vimdict, menu, keys...; kwargs...) - got == expected || push!(errs, :vim => got) - isempty(errs) || return errs -end + keydict = Dict(:up => "\e[A", + :down => "\e[B", + :enter => "\r") -function _simulate_input(keydict, menu::TerminalMenus.AbstractMenu, keys...; - kwargs...) for key in keys if isa(key, Symbol) write(stdin.buffer, keydict[key]) @@ -30,7 +18,7 @@ function _simulate_input(keydict, menu::TerminalMenus.AbstractMenu, keys...; end end - request(menu; suppress_output=true, kwargs...) + request(menu; suppress_output=true, kwargs...) == expected end include("radio_menu.jl") From afc7e72ee99d4ec44c00058f78c1b4e70bc9214e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C4=81K=C4=83?= Date: Tue, 10 Aug 2021 01:06:20 +0800 Subject: [PATCH 034/135] typo fix in documentation (#41838) --- doc/src/manual/running-external-programs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/manual/running-external-programs.md b/doc/src/manual/running-external-programs.md index 16dc779318d511..e643ffff3ee61d 100644 --- a/doc/src/manual/running-external-programs.md +++ b/doc/src/manual/running-external-programs.md @@ -399,7 +399,7 @@ julia> run(Cmd(`sh -c "echo foo \$HOWLONG"`, env=("HOWLONG" => "ever!",))); foo ever! ``` -See `[`Cmd`](@ref)` for additional keyword arguments. The [`setenv`](@ref) and [`addenv`](@ref) commands +See [`Cmd`](@ref) for additional keyword arguments. The [`setenv`](@ref) and [`addenv`](@ref) commands provide another means for replacing or adding to the `Cmd` execution environment variables, respectively: ```jldoctest From 727fe6aab165e53abd8231d0effbbfad54ba2863 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Mon, 9 Aug 2021 15:18:28 -0400 Subject: [PATCH 035/135] InteractiveUtils: print assembly code for code_native (#41789) The less reliable (and less verbose) disassembly version is selectable with dump_module=false. Fixes #38035 Fixes #29588 Fixes #39661 --- src/aotcompile.cpp | 97 +--------- src/disasm.cpp | 222 +++++++++++++++++++---- src/jitlayers.cpp | 11 +- src/jl_exported_funcs.inc | 2 +- src/julia_internal.h | 6 +- stdlib/InteractiveUtils/src/codeview.jl | 56 +++--- stdlib/InteractiveUtils/test/runtests.jl | 13 +- 7 files changed, 246 insertions(+), 161 deletions(-) diff --git a/src/aotcompile.cpp b/src/aotcompile.cpp index 96364d99048160..cb22bd80773412 100644 --- a/src/aotcompile.cpp +++ b/src/aotcompile.cpp @@ -5,11 +5,11 @@ // target support #include +#include +#include +#include #include #include -#include -#include -#include // analysis passes #include @@ -36,19 +36,11 @@ #endif #endif -// for outputting assembly +// for outputting code #include #include #include "llvm/Object/ArchiveWriter.h" #include -#include -#include -#include -#include -#include -#include -#include -#include #include #include @@ -494,10 +486,10 @@ void jl_dump_native(void *native_code, addTargetPasses(&PM, TM.get()); // set up optimization passes - SmallVector bc_Buffer; - SmallVector obj_Buffer; - SmallVector asm_Buffer; - SmallVector unopt_bc_Buffer; + SmallVector bc_Buffer; + SmallVector obj_Buffer; + SmallVector asm_Buffer; + SmallVector unopt_bc_Buffer; raw_svector_ostream bc_OS(bc_Buffer); raw_svector_ostream obj_OS(obj_Buffer); raw_svector_ostream asm_OS(asm_Buffer); @@ -864,7 +856,7 @@ void jl_add_optimization_passes(LLVMPassManagerRef PM, int opt_level, int lower_ // --- native code info, and dump function to IR and ASM --- // Get pointer to llvm::Function instance, compiling if necessary // for use in reflection from Julia. -// this is paired with jl_dump_function_ir, jl_dump_method_asm, jl_dump_llvm_asm in particular ways: +// this is paired with jl_dump_function_ir, jl_dump_function_asm, jl_dump_method_asm in particular ways: // misuse will leak memory or cause read-after-free extern "C" JL_DLLEXPORT void *jl_get_llvmf_defn(jl_method_instance_t *mi, size_t world, char getwrapper, char optimize, const jl_cgparams_t params) @@ -952,74 +944,3 @@ void *jl_get_llvmf_defn(jl_method_instance_t *mi, size_t world, char getwrapper, const char *mname = name_from_method_instance(mi); jl_errorf("unable to compile source for function %s", mname); } - -/// addPassesToX helper drives creation and initialization of TargetPassConfig. -static MCContext * -addPassesToGenerateCode(LLVMTargetMachine *TM, PassManagerBase &PM) { - TargetPassConfig *PassConfig = TM->createPassConfig(PM); - PassConfig->setDisableVerify(false); - PM.add(PassConfig); - MachineModuleInfoWrapperPass *MMIWP = - new MachineModuleInfoWrapperPass(TM); - PM.add(MMIWP); - if (PassConfig->addISelPasses()) - return NULL; - PassConfig->addMachinePasses(); - PassConfig->setInitialized(); - return &MMIWP->getMMI().getContext(); -} - -void jl_strip_llvm_debug(Module *m); - - -// get a native assembly for llvm::Function -// TODO: implement debuginfo handling -extern "C" JL_DLLEXPORT -jl_value_t *jl_dump_llvm_asm(void *F, const char* asm_variant, const char *debuginfo) -{ - // precise printing via IR assembler - SmallVector ObjBufferSV; - { // scope block - Function *f = (Function*)F; - llvm::raw_svector_ostream asmfile(ObjBufferSV); - assert(!f->isDeclaration()); - std::unique_ptr m(f->getParent()); - for (auto &f2 : m->functions()) { - if (f != &f2 && !f->isDeclaration()) - f2.deleteBody(); - } - jl_strip_llvm_debug(m.get()); - legacy::PassManager PM; - LLVMTargetMachine *TM = static_cast(jl_TargetMachine); - MCContext *Context = addPassesToGenerateCode(TM, PM); - if (Context) { - const MCSubtargetInfo &STI = *TM->getMCSubtargetInfo(); - const MCAsmInfo &MAI = *TM->getMCAsmInfo(); - const MCRegisterInfo &MRI = *TM->getMCRegisterInfo(); - const MCInstrInfo &MII = *TM->getMCInstrInfo(); - unsigned OutputAsmDialect = MAI.getAssemblerDialect(); - if (!strcmp(asm_variant, "att")) - OutputAsmDialect = 0; - if (!strcmp(asm_variant, "intel")) - OutputAsmDialect = 1; - MCInstPrinter *InstPrinter = TM->getTarget().createMCInstPrinter( - TM->getTargetTriple(), OutputAsmDialect, MAI, MII, MRI); - std::unique_ptr MAB(TM->getTarget().createMCAsmBackend( - STI, MRI, TM->Options.MCOptions)); - std::unique_ptr MCE; - auto FOut = std::make_unique(asmfile); - std::unique_ptr S(TM->getTarget().createAsmStreamer( - *Context, std::move(FOut), true, - true, InstPrinter, - std::move(MCE), std::move(MAB), - false)); - std::unique_ptr Printer( - TM->getTarget().createAsmPrinter(*TM, std::move(S))); - if (Printer) { - PM.add(Printer.release()); - PM.run(*m); - } - } - } - return jl_pchar_to_string(ObjBufferSV.data(), ObjBufferSV.size()); -} diff --git a/src/disasm.cpp b/src/disasm.cpp index dfc1e32b56eeb2..afcd8d65659e92 100644 --- a/src/disasm.cpp +++ b/src/disasm.cpp @@ -22,43 +22,53 @@ #include #include "llvm-version.h" -#include -#include + +// for outputting disassembly +#include +#include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include #include -#include -#include #include +#include +#include #include +#include +#include #include +#include +#include +#include +#include +#include #include -#include -#include -#include -#include +#include +#include #include +#include #include #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include + +// for outputting assembly +#include +#include +#include +#include +#include +#include #include #include "julia.h" @@ -279,20 +289,26 @@ void DILineInfoPrinter::emit_lineinfo(raw_ostream &Out, std::vector // adaptor class for printing line numbers before llvm IR lines class LineNumberAnnotatedWriter : public AssemblyAnnotationWriter { - DILocation *InstrLoc = nullptr; - DILineInfoPrinter LinePrinter{"; ", false}; + const DILocation *InstrLoc = nullptr; + DILineInfoPrinter LinePrinter; DenseMap DebugLoc; DenseMap Subprogram; public: - LineNumberAnnotatedWriter(const char *debuginfo) - { + LineNumberAnnotatedWriter(const char *LineStart, bool bracket_outer, const char *debuginfo) + : LinePrinter(LineStart, bracket_outer) { LinePrinter.SetVerbosity(debuginfo); } virtual void emitFunctionAnnot(const Function *, formatted_raw_ostream &); virtual void emitInstructionAnnot(const Instruction *, formatted_raw_ostream &); + virtual void emitInstructionAnnot(const DILocation *, formatted_raw_ostream &); virtual void emitBasicBlockEndAnnot(const BasicBlock *, formatted_raw_ostream &); // virtual void printInfoComment(const Value &, formatted_raw_ostream &) {} + void emitEnd(formatted_raw_ostream &Out) { + LinePrinter.emit_finish(Out); + InstrLoc = nullptr; + } + void addSubprogram(const Function *F, DISubprogram *SP) { Subprogram[F] = SP; @@ -327,12 +343,19 @@ void LineNumberAnnotatedWriter::emitFunctionAnnot( void LineNumberAnnotatedWriter::emitInstructionAnnot( const Instruction *I, formatted_raw_ostream &Out) { - DILocation *NewInstrLoc = I->getDebugLoc(); + const DILocation *NewInstrLoc = I->getDebugLoc(); if (!NewInstrLoc) { auto Loc = DebugLoc.find(I); if (Loc != DebugLoc.end()) NewInstrLoc = Loc->second; } + emitInstructionAnnot(NewInstrLoc, Out); + Out << LinePrinter.inlining_indent(" "); +} + +void LineNumberAnnotatedWriter::emitInstructionAnnot( + const DILocation *NewInstrLoc, formatted_raw_ostream &Out) +{ if (NewInstrLoc && NewInstrLoc != InstrLoc) { InstrLoc = NewInstrLoc; std::vector DIvec; @@ -348,14 +371,13 @@ void LineNumberAnnotatedWriter::emitInstructionAnnot( } while (NewInstrLoc); LinePrinter.emit_lineinfo(Out, DIvec); } - Out << LinePrinter.inlining_indent(" "); } void LineNumberAnnotatedWriter::emitBasicBlockEndAnnot( const BasicBlock *BB, formatted_raw_ostream &Out) { if (BB == &BB->getParent()->back()) - LinePrinter.emit_finish(Out); + emitEnd(Out); } static void jl_strip_llvm_debug(Module *m, bool all_meta, LineNumberAnnotatedWriter *AAW) @@ -435,7 +457,7 @@ jl_value_t *jl_dump_function_ir(void *f, char strip_ir_metadata, char dump_modul jl_error("jl_dump_function_ir: Expected Function* in a temporary Module"); JL_LOCK(&codegen_lock); // Might GC - LineNumberAnnotatedWriter AAW{debuginfo}; + LineNumberAnnotatedWriter AAW{"; ", false, debuginfo}; if (!llvmf->getParent()) { // print the function declaration as-is llvmf->print(stream, &AAW); @@ -507,7 +529,7 @@ static uint64_t compute_obj_symsize(object::SectionRef Section, uint64_t offset) // print a native disassembly for the function starting at fptr extern "C" JL_DLLEXPORT -jl_value_t *jl_dump_fptr_asm(uint64_t fptr, int raw_mc, const char* asm_variant, const char *debuginfo, char binary) +jl_value_t *jl_dump_fptr_asm(uint64_t fptr, char raw_mc, const char* asm_variant, const char *debuginfo, char binary) { assert(fptr != 0); std::string code; @@ -1046,6 +1068,138 @@ static void jl_dump_asm_internal( } } +/// addPassesToX helper drives creation and initialization of TargetPassConfig. +static MCContext * +addPassesToGenerateCode(LLVMTargetMachine *TM, PassManagerBase &PM) { + TargetPassConfig *PassConfig = TM->createPassConfig(PM); + PassConfig->setDisableVerify(false); + PM.add(PassConfig); + MachineModuleInfoWrapperPass *MMIWP = + new MachineModuleInfoWrapperPass(TM); + PM.add(MMIWP); + if (PassConfig->addISelPasses()) + return NULL; + PassConfig->addMachinePasses(); + PassConfig->setInitialized(); + return &MMIWP->getMMI().getContext(); +} + +class LineNumberPrinterHandler : public AsmPrinterHandler { + MCStreamer &S; + LineNumberAnnotatedWriter LinePrinter; + std::string Buffer; + llvm::raw_string_ostream RawStream; + llvm::formatted_raw_ostream Stream; + +public: + LineNumberPrinterHandler(AsmPrinter &Printer, const char *debuginfo) + : S(*Printer.OutStreamer), + LinePrinter("; ", true, debuginfo), + RawStream(Buffer), + Stream(RawStream) {} + + void emitAndReset() { + Stream.flush(); + RawStream.flush(); + if (Buffer.empty()) + return; + S.emitRawText(Buffer); + Buffer.clear(); + } + + virtual void setSymbolSize(const MCSymbol *Sym, uint64_t Size) override {} + //virtual void beginModule(Module *M) override {} + virtual void endModule() override {} + /// note that some AsmPrinter implementations may not call beginFunction at all + virtual void beginFunction(const MachineFunction *MF) override { + LinePrinter.emitFunctionAnnot(&MF->getFunction(), Stream); + emitAndReset(); + } + //virtual void markFunctionEnd() override {} + virtual void endFunction(const MachineFunction *MF) override { + LinePrinter.emitEnd(Stream); + emitAndReset(); + } + //virtual void beginFragment(const MachineBasicBlock *MBB, + // ExceptionSymbolProvider ESP) override {} + //virtual void endFragment() override {} + //virtual void beginFunclet(const MachineBasicBlock &MBB, + // MCSymbol *Sym = nullptr) override {} + //virtual void endFunclet() override {} + virtual void beginInstruction(const MachineInstr *MI) override { + LinePrinter.emitInstructionAnnot(MI->getDebugLoc(), Stream); + emitAndReset(); + } + virtual void endInstruction() override {} +}; + +// get a native assembly for llvm::Function +extern "C" JL_DLLEXPORT +jl_value_t *jl_dump_function_asm(void *F, char raw_mc, const char* asm_variant, const char *debuginfo, char binary) +{ + // precise printing via IR assembler + SmallVector ObjBufferSV; + { // scope block + Function *f = (Function*)F; + llvm::raw_svector_ostream asmfile(ObjBufferSV); + assert(!f->isDeclaration()); + std::unique_ptr m(f->getParent()); + for (auto &f2 : m->functions()) { + if (f != &f2 && !f->isDeclaration()) + f2.deleteBody(); + } + LLVMTargetMachine *TM = static_cast(jl_TargetMachine); + legacy::PassManager PM; + addTargetPasses(&PM, TM); + if (raw_mc) { + raw_svector_ostream obj_OS(ObjBufferSV); + if (TM->addPassesToEmitFile(PM, obj_OS, nullptr, CGFT_ObjectFile, false, nullptr)) + return jl_an_empty_string; + PM.run(*m); + } + else { + MCContext *Context = addPassesToGenerateCode(TM, PM); + if (!Context) + return jl_an_empty_string; + Context->setGenDwarfForAssembly(false); + // Duplicate LLVMTargetMachine::addAsmPrinter here so we can set the asm dialect and add the custom annotation printer + const MCSubtargetInfo &STI = *TM->getMCSubtargetInfo(); + const MCAsmInfo &MAI = *TM->getMCAsmInfo(); + const MCRegisterInfo &MRI = *TM->getMCRegisterInfo(); + const MCInstrInfo &MII = *TM->getMCInstrInfo(); + unsigned OutputAsmDialect = MAI.getAssemblerDialect(); + if (!strcmp(asm_variant, "att")) + OutputAsmDialect = 0; + if (!strcmp(asm_variant, "intel")) + OutputAsmDialect = 1; + MCInstPrinter *InstPrinter = TM->getTarget().createMCInstPrinter( + TM->getTargetTriple(), OutputAsmDialect, MAI, MII, MRI); + std::unique_ptr MAB(TM->getTarget().createMCAsmBackend( + STI, MRI, TM->Options.MCOptions)); + std::unique_ptr MCE; + if (binary) // enable MCAsmStreamer::AddEncodingComment printing + MCE.reset(TM->getTarget().createMCCodeEmitter(MII, MRI, *Context)); + auto FOut = std::make_unique(asmfile); + std::unique_ptr S(TM->getTarget().createAsmStreamer( + *Context, std::move(FOut), true, + true, InstPrinter, + std::move(MCE), std::move(MAB), + false)); + std::unique_ptr Printer( + TM->getTarget().createAsmPrinter(*TM, std::move(S))); + Printer->addAsmPrinterHandler(AsmPrinter::HandlerInfo( + std::unique_ptr(new LineNumberPrinterHandler(*Printer, debuginfo)), + "emit", "Debug Info Emission", "Julia", "Julia::LineNumberPrinterHandler Markup")); + if (!Printer) + return jl_an_empty_string; + PM.add(Printer.release()); + PM.add(createFreeMachineFunctionPass()); + PM.run(*m); + } + } + return jl_pchar_to_string(ObjBufferSV.data(), ObjBufferSV.size()); +} + extern "C" JL_DLLEXPORT LLVMDisasmContextRef jl_LLVMCreateDisasm( const char *TripleName, void *DisInfo, int TagType, diff --git a/src/jitlayers.cpp b/src/jitlayers.cpp index e86d6109ff4275..92af6ae460004c 100644 --- a/src/jitlayers.cpp +++ b/src/jitlayers.cpp @@ -181,7 +181,7 @@ static jl_callptr_t _jl_compile_codeinst( jl_atomic_store_release(&this_code->invoke, addr); } else if (this_code->invoke == jl_fptr_const_return && !decls.specFunctionObject.empty()) { - // hack to export this pointer value to jl_dump_method_asm + // hack to export this pointer value to jl_dump_method_disasm this_code->specptr.fptr = (void*)getAddressForFunction(decls.specFunctionObject); } if (this_code== codeinst) @@ -407,7 +407,7 @@ void jl_generate_fptr_for_unspecialized(jl_code_instance_t *unspec) // get a native disassembly for a compiled method extern "C" JL_DLLEXPORT jl_value_t *jl_dump_method_asm(jl_method_instance_t *mi, size_t world, - int raw_mc, char getwrapper, const char* asm_variant, const char *debuginfo, char binary) + char raw_mc, char getwrapper, const char* asm_variant, const char *debuginfo, char binary) { // printing via disassembly jl_code_instance_t *codeinst = jl_generate_fptr(mi, world); @@ -457,9 +457,10 @@ jl_value_t *jl_dump_method_asm(jl_method_instance_t *mi, size_t world, } // whatever, that didn't work - use the assembler output instead - if (raw_mc) // eh, give up, this flag doesn't really work anyways normally - return (jl_value_t*)jl_pchar_to_array("", 0); - return jl_dump_llvm_asm(jl_get_llvmf_defn(mi, world, getwrapper, true, jl_default_cgparams), asm_variant, debuginfo); + void *F = jl_get_llvmf_defn(mi, world, getwrapper, true, jl_default_cgparams); + if (!F) + return jl_an_empty_string; + return jl_dump_function_asm(F, raw_mc, asm_variant, debuginfo, binary); } // A simple forwarding class, since OrcJIT v2 needs a unique_ptr, while we have a shared_ptr diff --git a/src/jl_exported_funcs.inc b/src/jl_exported_funcs.inc index 8e2c21fb6dfeca..c85b1a48e2ba49 100644 --- a/src/jl_exported_funcs.inc +++ b/src/jl_exported_funcs.inc @@ -120,9 +120,9 @@ XX(jl_dlsym) \ XX(jl_dump_compiles) \ XX(jl_dump_fptr_asm) \ + XX(jl_dump_function_asm) \ XX(jl_dump_function_ir) \ XX(jl_dump_host_cpu) \ - XX(jl_dump_llvm_asm) \ XX(jl_dump_method_asm) \ XX(jl_egal) \ XX(jl_egal__bits) \ diff --git a/src/julia_internal.h b/src/julia_internal.h index b997ad0d1214a7..8f2f87acca3fed 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -798,11 +798,11 @@ static inline void jl_set_gc_and_wait(void) void jl_gc_set_permalloc_region(void *start, void *end); JL_DLLEXPORT jl_value_t *jl_dump_method_asm(jl_method_instance_t *linfo, size_t world, - int raw_mc, char getwrapper, const char* asm_variant, const char *debuginfo, char binary); + char raw_mc, char getwrapper, const char* asm_variant, const char *debuginfo, char binary); JL_DLLEXPORT void *jl_get_llvmf_defn(jl_method_instance_t *linfo, size_t world, char getwrapper, char optimize, const jl_cgparams_t params); -JL_DLLEXPORT jl_value_t *jl_dump_fptr_asm(uint64_t fptr, int raw_mc, const char* asm_variant, const char *debuginfo, char binary); -JL_DLLEXPORT jl_value_t *jl_dump_llvm_asm(void *F, const char* asm_variant, const char *debuginfo); +JL_DLLEXPORT jl_value_t *jl_dump_fptr_asm(uint64_t fptr, char raw_mc, const char* asm_variant, const char *debuginfo, char binary); JL_DLLEXPORT jl_value_t *jl_dump_function_ir(void *f, char strip_ir_metadata, char dump_module, const char *debuginfo); +JL_DLLEXPORT jl_value_t *jl_dump_function_asm(void *F, char raw_mc, const char* asm_variant, const char *debuginfo, char binary); void *jl_create_native(jl_array_t *methods, const jl_cgparams_t cgparams, int policy); void jl_dump_native(void *native_code, diff --git a/stdlib/InteractiveUtils/src/codeview.jl b/stdlib/InteractiveUtils/src/codeview.jl index d6f7cd9daa24d3..b292324a17134f 100644 --- a/stdlib/InteractiveUtils/src/codeview.jl +++ b/stdlib/InteractiveUtils/src/codeview.jl @@ -143,7 +143,7 @@ import Base.CodegenParams function _dump_function(@nospecialize(f), @nospecialize(t), native::Bool, wrapper::Bool, strip_ir_metadata::Bool, dump_module::Bool, syntax::Symbol, optimize::Bool, debuginfo::Symbol, binary::Bool, - params::CodegenParams=CodegenParams()) + params::CodegenParams=CodegenParams(debug_info_kind=Cint(0))) ccall(:jl_is_in_pure_context, Bool, ()) && error("code reflection cannot be used from generated functions") if isa(f, Core.Builtin) throw(ArgumentError("argument is not a generic function")) @@ -153,8 +153,20 @@ function _dump_function(@nospecialize(f), @nospecialize(t), native::Bool, wrappe match = Base._which(signature_type(f, t), world) linfo = Core.Compiler.specialize_method(match) # get the code for it + if debuginfo === :default + debuginfo = :source + elseif debuginfo !== :source && debuginfo !== :none + throw(ArgumentError("'debuginfo' must be either :source or :none")) + end if native - str = _dump_function_linfo_native(linfo, world, wrapper, syntax, debuginfo, binary) + if syntax !== :att && syntax !== :intel + throw(ArgumentError("'syntax' must be either :intel or :att")) + end + if dump_module + str = _dump_function_linfo_native(linfo, world, wrapper, syntax, debuginfo, binary, params) + else + str = _dump_function_linfo_native(linfo, world, wrapper, syntax, debuginfo, binary) + end else str = _dump_function_linfo_llvm(linfo, world, wrapper, strip_ir_metadata, dump_module, optimize, debuginfo, params) end @@ -164,17 +176,18 @@ function _dump_function(@nospecialize(f), @nospecialize(t), native::Bool, wrappe end function _dump_function_linfo_native(linfo::Core.MethodInstance, world::UInt, wrapper::Bool, syntax::Symbol, debuginfo::Symbol, binary::Bool) - if syntax !== :att && syntax !== :intel - throw(ArgumentError("'syntax' must be either :intel or :att")) - end - if debuginfo === :default - debuginfo = :source - elseif debuginfo !== :source && debuginfo !== :none - throw(ArgumentError("'debuginfo' must be either :source or :none")) - end str = ccall(:jl_dump_method_asm, Ref{String}, - (Any, UInt, Cint, Bool, Ptr{UInt8}, Ptr{UInt8}, Bool), - linfo, world, 0, wrapper, syntax, debuginfo, binary) + (Any, UInt, Bool, Bool, Ptr{UInt8}, Ptr{UInt8}, Bool), + linfo, world, false, wrapper, syntax, debuginfo, binary) + return str +end + +function _dump_function_linfo_native(linfo::Core.MethodInstance, world::UInt, wrapper::Bool, syntax::Symbol, debuginfo::Symbol, binary::Bool, params::CodegenParams) + llvmf = ccall(:jl_get_llvmf_defn, Ptr{Cvoid}, (Any, UInt, Bool, Bool, CodegenParams), linfo, world, wrapper, true, params) + llvmf == C_NULL && error("could not compile the specified method") + str = ccall(:jl_dump_function_asm, Ref{String}, + (Ptr{Cvoid}, Bool, Ptr{UInt8}, Ptr{UInt8}, Bool), + llvmf, false, syntax, debuginfo, binary) return str end @@ -183,11 +196,6 @@ function _dump_function_linfo_llvm( strip_ir_metadata::Bool, dump_module::Bool, optimize::Bool, debuginfo::Symbol, params::CodegenParams) - if debuginfo === :default - debuginfo = :source - elseif debuginfo !== :source && debuginfo !== :none - throw(ArgumentError("'debuginfo' must be either :source or :none")) - end llvmf = ccall(:jl_get_llvmf_defn, Ptr{Cvoid}, (Any, UInt, Bool, Bool, CodegenParams), linfo, world, wrapper, optimize, params) llvmf == C_NULL && error("could not compile the specified method") str = ccall(:jl_dump_function_ir, Ref{String}, @@ -219,11 +227,11 @@ end code_llvm(io::IO, @nospecialize(f), @nospecialize(types=Tuple); raw::Bool=false, dump_module::Bool=false, optimize::Bool=true, debuginfo::Symbol=:default) = code_llvm(io, f, types, raw, dump_module, optimize, debuginfo) code_llvm(@nospecialize(f), @nospecialize(types=Tuple); raw=false, dump_module=false, optimize=true, debuginfo::Symbol=:default) = - code_llvm(stdout, f, types; raw=raw, dump_module=dump_module, optimize=optimize, debuginfo=debuginfo) + code_llvm(stdout, f, types; raw, dump_module, optimize, debuginfo) """ - code_native([io=stdout,], f, types; syntax=:att, debuginfo=:default, binary=false) + code_native([io=stdout,], f, types; syntax=:att, debuginfo=:default, binary=false, dump_module=true) Prints the native assembly instructions generated for running the method matching the given generic function and type signature to `io`. @@ -232,17 +240,17 @@ Keyword argument `debuginfo` may be one of source (default) or none, to specify If `binary` is `true`, it also prints the binary machine code for each instruction precedented by an abbreviated address. """ function code_native(io::IO, @nospecialize(f), @nospecialize(types=Tuple); - syntax::Symbol=:att, debuginfo::Symbol=:default, binary::Bool=false) - d = _dump_function(f, types, true, false, false, false, syntax, true, debuginfo, binary) + dump_module::Bool=true, syntax::Symbol=:att, debuginfo::Symbol=:default, binary::Bool=false) + d = _dump_function(f, types, true, false, false, dump_module, syntax, true, debuginfo, binary) if highlighting[:native] && get(io, :color, false) print_native(io, d) else print(io, d) end end -code_native(@nospecialize(f), @nospecialize(types=Tuple); syntax::Symbol=:att, debuginfo::Symbol=:default, binary::Bool=false) = - code_native(stdout, f, types; syntax=syntax, debuginfo=debuginfo, binary=binary) -code_native(::IO, ::Any, ::Symbol) = error("illegal code_native call") # resolve ambiguous call +code_native(@nospecialize(f), @nospecialize(types=Tuple); dump_module::Bool=true, syntax::Symbol=:att, debuginfo::Symbol=:default, binary::Bool=false) = + code_native(stdout, f, types; dump_module, syntax, debuginfo, binary) +code_native(::IO, ::Any, ::Symbol) = error("invalid code_native call") # resolve ambiguous call ## colorized IR and assembly printing diff --git a/stdlib/InteractiveUtils/test/runtests.jl b/stdlib/InteractiveUtils/test/runtests.jl index 8770de8797f045..8258881f567110 100644 --- a/stdlib/InteractiveUtils/test/runtests.jl +++ b/stdlib/InteractiveUtils/test/runtests.jl @@ -331,7 +331,7 @@ let err = tempname(), redirect_stderr(new_stderr) println(new_stderr, "start") flush(new_stderr) - @eval @test occursin("h_broken_code", sprint(code_native, h_broken_code, ())) + @test occursin("h_broken_code", sprint(code_native, h_broken_code, ())) Libc.flush_cstdio() println(new_stderr, "end") flush(new_stderr) @@ -341,10 +341,11 @@ let err = tempname(), close(new_stderr) let errstr = read(err, String) @test startswith(errstr, """start + end Internal error: encountered unexpected error during compilation of f_broken_code: ErrorException(\"unsupported or misplaced expression \"invalid\" in function f_broken_code\") """) || errstr - @test endswith(errstr, "\nend\n") || errstr + @test !endswith(errstr, "\nend\n") || errstr end rm(err) end @@ -444,12 +445,12 @@ if Sys.ARCH === :x86_64 || occursin(ix86, string(Sys.ARCH)) buf = IOBuffer() #test that the string output is at&t syntax by checking for occurrences of '%'s code_native(buf, linear_foo, (), syntax = :att, debuginfo = :none) - output = String(take!(buf)) + output = replace(String(take!(buf)), r"#[^\r\n]+" => "") @test occursin(rgx, output) #test that the code output is intel syntax by checking it has no occurrences of '%' code_native(buf, linear_foo, (), syntax = :intel, debuginfo = :none) - output = String(take!(buf)) + output = replace(String(take!(buf)), r"#[^\r\n]+" => "") @test !occursin(rgx, output) code_native(buf, linear_foo, ()) @@ -461,13 +462,13 @@ if Sys.ARCH === :x86_64 || occursin(ix86, string(Sys.ARCH)) ret = r"^; [0-9a-f]{4}: c3$"m # without binary flag (default) - code_native(buf, linear_foo, ()) + code_native(buf, linear_foo, (), dump_module=false) output = String(take!(buf)) @test !occursin(ret, output) # with binary flag for binary in false:true - code_native(buf, linear_foo, (), binary = binary) + code_native(buf, linear_foo, (); binary, dump_module=false) output = String(take!(buf)) @test occursin(ret, output) == binary end From a1e9fd33ad587c3a72240324a43b198b6702df33 Mon Sep 17 00:00:00 2001 From: Thomas Christensen Date: Mon, 9 Aug 2021 16:41:08 -0400 Subject: [PATCH 036/135] nit type-stability in `StackTraces.lookup` `line` variable (#41847) --- base/stacktraces.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/stacktraces.jl b/base/stacktraces.jl index 99ee5c57db89f8..8483aec55cbffc 100644 --- a/base/stacktraces.jl +++ b/base/stacktraces.jl @@ -133,7 +133,7 @@ function lookup(ip::Union{Base.InterpreterIP,Core.Compiler.InterpreterIP}) else func = top_level_scope_sym file = empty_sym - line = 0 + line = Int32(0) end i = max(ip.stmt+1, 1) # ip.stmt is 0-indexed if i > length(codeinfo.codelocs) || codeinfo.codelocs[i] == 0 From 68c458519d369d922e1bfc2c8f9bb240c8718eaa Mon Sep 17 00:00:00 2001 From: DilumAluthgeBot <43731525+DilumAluthgeBot@users.noreply.github.com> Date: Mon, 9 Aug 2021 21:49:44 +0000 Subject: [PATCH 037/135] =?UTF-8?q?=F0=9F=A4=96=20Bump=20the=20Downloads?= =?UTF-8?q?=20stdlib=20from=20cd002c3=20to=20848d374=20(#41803)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Dilum Aluthge --- .../md5 | 1 + .../sha512 | 1 + .../md5 | 1 - .../sha512 | 1 - stdlib/Downloads.version | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 deps/checksums/Downloads-848d374fc563fa9dc6b4d5e6e5be5ad2022652a7.tar.gz/md5 create mode 100644 deps/checksums/Downloads-848d374fc563fa9dc6b4d5e6e5be5ad2022652a7.tar.gz/sha512 delete mode 100644 deps/checksums/Downloads-cd002c3c6936d144ae668d70e18337931706c63a.tar.gz/md5 delete mode 100644 deps/checksums/Downloads-cd002c3c6936d144ae668d70e18337931706c63a.tar.gz/sha512 diff --git a/deps/checksums/Downloads-848d374fc563fa9dc6b4d5e6e5be5ad2022652a7.tar.gz/md5 b/deps/checksums/Downloads-848d374fc563fa9dc6b4d5e6e5be5ad2022652a7.tar.gz/md5 new file mode 100644 index 00000000000000..f15a75d37a9199 --- /dev/null +++ b/deps/checksums/Downloads-848d374fc563fa9dc6b4d5e6e5be5ad2022652a7.tar.gz/md5 @@ -0,0 +1 @@ +1e360a7f928fdf69dc847cbbd28010f0 diff --git a/deps/checksums/Downloads-848d374fc563fa9dc6b4d5e6e5be5ad2022652a7.tar.gz/sha512 b/deps/checksums/Downloads-848d374fc563fa9dc6b4d5e6e5be5ad2022652a7.tar.gz/sha512 new file mode 100644 index 00000000000000..603b2e4be35f2d --- /dev/null +++ b/deps/checksums/Downloads-848d374fc563fa9dc6b4d5e6e5be5ad2022652a7.tar.gz/sha512 @@ -0,0 +1 @@ +b9df90fc9d5bce2b8d1ed2c800fd0666e3f2ac85f802da4fcbab93ed2894310f90d0ea10ebe1c859c8faa8ddb4e1cef58aa72c1e0decf03f44fa3f3eabb1bcce diff --git a/deps/checksums/Downloads-cd002c3c6936d144ae668d70e18337931706c63a.tar.gz/md5 b/deps/checksums/Downloads-cd002c3c6936d144ae668d70e18337931706c63a.tar.gz/md5 deleted file mode 100644 index 8b51d12bf97931..00000000000000 --- a/deps/checksums/Downloads-cd002c3c6936d144ae668d70e18337931706c63a.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -53ebf53c712444f7a7e4b2b4507ed675 diff --git a/deps/checksums/Downloads-cd002c3c6936d144ae668d70e18337931706c63a.tar.gz/sha512 b/deps/checksums/Downloads-cd002c3c6936d144ae668d70e18337931706c63a.tar.gz/sha512 deleted file mode 100644 index 05665fb161f204..00000000000000 --- a/deps/checksums/Downloads-cd002c3c6936d144ae668d70e18337931706c63a.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -3d058995add04e2cf37b61e2c39b1606c63e50edee6d7945b59078df3f05b39b86333d03e48832871101793342182055cb604a7b0565d82b2740dedac4248461 diff --git a/stdlib/Downloads.version b/stdlib/Downloads.version index 8ac1bc22f228ae..51f7f8d24d2f36 100644 --- a/stdlib/Downloads.version +++ b/stdlib/Downloads.version @@ -1,2 +1,2 @@ DOWNLOADS_BRANCH = master -DOWNLOADS_SHA1 = cd002c3c6936d144ae668d70e18337931706c63a +DOWNLOADS_SHA1 = 848d374fc563fa9dc6b4d5e6e5be5ad2022652a7 From cd6e67f38bc8ffcd4fbb05971452630609649a91 Mon Sep 17 00:00:00 2001 From: Tim Besard Date: Tue, 10 Aug 2021 08:02:17 +0200 Subject: [PATCH 038/135] Include an additional patch for OpenBLAS. (#41842) Fixes dynamic arch detection on certain ARMv8 cores. See https://github.com/xianyi/OpenBLAS/pull/3060 --- deps/checksums/openblas | 184 +++++++++--------- deps/openblas.mk | 7 +- .../openblas-armv8-volatile-detecion.patch | 23 +++ stdlib/OpenBLAS_jll/Project.toml | 2 +- 4 files changed, 122 insertions(+), 94 deletions(-) create mode 100644 deps/patches/openblas-armv8-volatile-detecion.patch diff --git a/deps/checksums/openblas b/deps/checksums/openblas index 4b4d477ddc3d27..5a1668aa452544 100644 --- a/deps/checksums/openblas +++ b/deps/checksums/openblas @@ -1,92 +1,92 @@ -OpenBLAS.v0.3.13+6.aarch64-apple-darwin-libgfortran5.tar.gz/md5/db35f9fcf744a3d86c0a20b8ab39c7c1 -OpenBLAS.v0.3.13+6.aarch64-apple-darwin-libgfortran5.tar.gz/sha512/45ffdac8aa4150e96981cdc3d32242ebf7b7987fed5408d6cd6a9a6518cf7b7f204ca2a4226a0837cae76c2d4d4822d4ae93d2de1164428830c04e2147976341 -OpenBLAS.v0.3.13+6.aarch64-linux-gnu-libgfortran3.tar.gz/md5/aecd6bc6356314108c4ef2bfd768d006 -OpenBLAS.v0.3.13+6.aarch64-linux-gnu-libgfortran3.tar.gz/sha512/1f5e861d3e14d64d0574a4dde4909f21cc0c22d1bfe052aae93a7ba3b3a9e564e01a7e1c921cb6175ba251a8aadfb0c4fce345803966dd7452db3d289bf144d3 -OpenBLAS.v0.3.13+6.aarch64-linux-gnu-libgfortran4.tar.gz/md5/7d20f2dd20459cee45adb024adb43efd -OpenBLAS.v0.3.13+6.aarch64-linux-gnu-libgfortran4.tar.gz/sha512/b06dcbf820f74e3e3cda4cfdf76113e7f518639642f141dac13ca19b05fec09160c3728fb4f7b001a9aa63300f6e289cd2126da1179ef4efce18e814d8c32bbf -OpenBLAS.v0.3.13+6.aarch64-linux-gnu-libgfortran5.tar.gz/md5/5f0a683b55fc2f5a4dcd134a0d03c175 -OpenBLAS.v0.3.13+6.aarch64-linux-gnu-libgfortran5.tar.gz/sha512/89c25976dd89e2e1c856790aaa4d0951f912fd7ded92223952316e40b08e4b9d9218b25a35cf9ab19021b356ccbb72c8bab2237bc62b8dac37317abe31edff6d -OpenBLAS.v0.3.13+6.aarch64-linux-musl-libgfortran3.tar.gz/md5/5a7815b5981d30b89cb48a3e3bbf8f4d -OpenBLAS.v0.3.13+6.aarch64-linux-musl-libgfortran3.tar.gz/sha512/358b7d25a069d50434b6621d1831903b88f6e120f10b5978235cc82f795da4d31ca4e6d02eb5eb1fd5587085828e95835e2ad84b2042865c552c5493cc272227 -OpenBLAS.v0.3.13+6.aarch64-linux-musl-libgfortran4.tar.gz/md5/02062032841900e941cfc66a0ef94dae -OpenBLAS.v0.3.13+6.aarch64-linux-musl-libgfortran4.tar.gz/sha512/86f3072c3b8e36f3b33d90da755bf9d2a95ba0317852eaf1c74deb8a0f62a2b5c19a3b1d551c054536277da50865ef341c5e05fbab195edc4cd1fb160b4203b8 -OpenBLAS.v0.3.13+6.aarch64-linux-musl-libgfortran5.tar.gz/md5/ec50a9a3e5078726d6e3dd011b7a4713 -OpenBLAS.v0.3.13+6.aarch64-linux-musl-libgfortran5.tar.gz/sha512/548d4b893648de6c1a3d6b24f4531c4b190afc338887d1b8eb9040a9aae72cf846127e9c545841568a2f358f090451e13cf12a191456d4c27431661ca41f6e10 -OpenBLAS.v0.3.13+6.armv6l-linux-gnueabihf-libgfortran3.tar.gz/md5/15cb058e906a1f042d51e8dcc44dac90 -OpenBLAS.v0.3.13+6.armv6l-linux-gnueabihf-libgfortran3.tar.gz/sha512/d74ba1d83199259b07787424832318e31013384d4f7217f6d7adb47dcbfe0836147997c044c8ca7a27b5a5eea435948a42d7f81a38014b7f7b3f4fb049e3578b -OpenBLAS.v0.3.13+6.armv6l-linux-gnueabihf-libgfortran4.tar.gz/md5/14b991b59eb27538331fae0544130d8a -OpenBLAS.v0.3.13+6.armv6l-linux-gnueabihf-libgfortran4.tar.gz/sha512/d2c194692265325f9e5b6c09c23d7dcb45f1f2ce88edf2fbe6f9b021bfedf6b0c7c4b94a7ff5aa7095b7a131870759cd81ec80369e315660f5cbb0ac1c133e76 -OpenBLAS.v0.3.13+6.armv6l-linux-gnueabihf-libgfortran5.tar.gz/md5/161a6506630eb035bc6afae69aea91dd -OpenBLAS.v0.3.13+6.armv6l-linux-gnueabihf-libgfortran5.tar.gz/sha512/f64ce6bbaac4e16d5956b6298204628648b35e76f14a528aa8df815b0021053e4e1963438edc7e5f66fd82ea1e1d7bc38b14c52ad0ea7b90eeb1ee59d0927fd8 -OpenBLAS.v0.3.13+6.armv6l-linux-musleabihf-libgfortran3.tar.gz/md5/b4d102165aff04f4a3ff583c754ec90c -OpenBLAS.v0.3.13+6.armv6l-linux-musleabihf-libgfortran3.tar.gz/sha512/f488da922deaac3fa42f5637003c9dbfd943aa267104e6fce46b77fd9f10dfc580191bd5aa4c97bf5b41ad6a92fd669daca8b11479a3a7e28f41047826f0e6bd -OpenBLAS.v0.3.13+6.armv6l-linux-musleabihf-libgfortran4.tar.gz/md5/9411f83736cbcef0b840914ace71d869 -OpenBLAS.v0.3.13+6.armv6l-linux-musleabihf-libgfortran4.tar.gz/sha512/3b0c9077255fa639d8798193fb1c5fd8ad7824f58889d0c99b388b3ddc7622122387acc49fc29f7c5b5a62ff7dd2335a47b6e60c14d613ba37e11b79faddf7d2 -OpenBLAS.v0.3.13+6.armv6l-linux-musleabihf-libgfortran5.tar.gz/md5/1222f66dbd5eb8dc910efe04d37fb763 -OpenBLAS.v0.3.13+6.armv6l-linux-musleabihf-libgfortran5.tar.gz/sha512/a747df8a04d50ef4a4b90bb66e682cd7414b6d2f0cd9577e25b18c80d36b599e9506e8fcf24729a8bc0f5ef464c57d86a87e1e74140597466dbd862eeb9a0b18 -OpenBLAS.v0.3.13+6.armv7l-linux-gnueabihf-libgfortran3.tar.gz/md5/35fd828c77d3e1817bebef49aa045f02 -OpenBLAS.v0.3.13+6.armv7l-linux-gnueabihf-libgfortran3.tar.gz/sha512/fd4ce90ea21f64abde4497d3d6518c341383eae4c8f5052951b5c1469c87f1464cc1c57f7047bd4881b55d70d6453ef558e6d6e1986fe463a98a0567bbb876a5 -OpenBLAS.v0.3.13+6.armv7l-linux-gnueabihf-libgfortran4.tar.gz/md5/deaa63f74369dbf358946c6796e8bd6b -OpenBLAS.v0.3.13+6.armv7l-linux-gnueabihf-libgfortran4.tar.gz/sha512/7b16a7f5b5710de0b38122af6ed9e4a6b3ede4cd9c18c79314fbde366ca92c2dae17d1ab9e43213b5a6f80470455afbb06d54ff326e0404d60f5454164f2c62a -OpenBLAS.v0.3.13+6.armv7l-linux-gnueabihf-libgfortran5.tar.gz/md5/450506080f49538628dc2407461b894d -OpenBLAS.v0.3.13+6.armv7l-linux-gnueabihf-libgfortran5.tar.gz/sha512/95dc7f14c1b1f450de59a3f95673dc510bcd0e38b6d82a8657d4dbdd97158d2095002a61ecb4a4c514e530c0a9879afd232f24a71561e8516683c564406a0a55 -OpenBLAS.v0.3.13+6.armv7l-linux-musleabihf-libgfortran3.tar.gz/md5/cadda67c770ea3835170c63cf5c1a93f -OpenBLAS.v0.3.13+6.armv7l-linux-musleabihf-libgfortran3.tar.gz/sha512/ccd326df1d3ce8e138fc22db37880a0f15b3b5740b75f4d6e54c6496735dea48d1011c31d0fbf6fcaf7f4ccc565cb2aa59bac473b9b12251da1adaa992998373 -OpenBLAS.v0.3.13+6.armv7l-linux-musleabihf-libgfortran4.tar.gz/md5/e89c9935ed19d9b6bedd1b70cbe1ea27 -OpenBLAS.v0.3.13+6.armv7l-linux-musleabihf-libgfortran4.tar.gz/sha512/d537e954d424240315280fe632bfa83088825dd770042a750448e1553b2887a8c3d4edf193c89d2bccb7b0c3eae560937156eb989373accca1dbecee47e32cc4 -OpenBLAS.v0.3.13+6.armv7l-linux-musleabihf-libgfortran5.tar.gz/md5/7072bd88910ce5402e18527f178dcd56 -OpenBLAS.v0.3.13+6.armv7l-linux-musleabihf-libgfortran5.tar.gz/sha512/0e4e038f317faa7a14cc29267202ad781a2551ef444b27f841ad2a39f5fb5032d20d50749d1b5a925e6552247aca40d84a1464c268022d8b9560c6e6fcf9a9bd -OpenBLAS.v0.3.13+6.i686-linux-gnu-libgfortran3.tar.gz/md5/261636c2b2b3a734e0d054b67fc0e617 -OpenBLAS.v0.3.13+6.i686-linux-gnu-libgfortran3.tar.gz/sha512/0777c0cccb6f688024756e12f8a09ca107cf6f2408d04fb1efeae67299eb8de834de158b9ada232e3e50d4bb0481810181c54f6b63238ba8d4f1a779bf30ceab -OpenBLAS.v0.3.13+6.i686-linux-gnu-libgfortran4.tar.gz/md5/af9998d911a0919bbc611279f6957d8f -OpenBLAS.v0.3.13+6.i686-linux-gnu-libgfortran4.tar.gz/sha512/639d0d837dd62f4eff32071e2ef5d95d3d1a80995dc9da0a97e0a2f8bedf4637e3082acec309744d0d36dca8e82b3f7bf792ffb9ba47c18d8b9a44aa0f368adf -OpenBLAS.v0.3.13+6.i686-linux-gnu-libgfortran5.tar.gz/md5/7bee1a7c3470c32c10e3776289ce730f -OpenBLAS.v0.3.13+6.i686-linux-gnu-libgfortran5.tar.gz/sha512/ff76d5fc5ff2432dfcd9a36cfb95943fecab3e75153c12260b729a89c6bc2269f7f0ad256f6334d58445de27d32f6073e830cee4a59e9196a0b7395c3a3b7ab0 -OpenBLAS.v0.3.13+6.i686-linux-musl-libgfortran3.tar.gz/md5/362e299c65ed4011563caf8555f55738 -OpenBLAS.v0.3.13+6.i686-linux-musl-libgfortran3.tar.gz/sha512/45eeae6bc817e8d78c0daa69ca2add3c32d714766e1e1341d14c445a1beb5a5a7ae93e88649c9a62f07c5463b6ee300b60acc06d9d29974cc6725d08d9df66d9 -OpenBLAS.v0.3.13+6.i686-linux-musl-libgfortran4.tar.gz/md5/791075ccd19280d58209f48b487ec42b -OpenBLAS.v0.3.13+6.i686-linux-musl-libgfortran4.tar.gz/sha512/44b9bf0b5d31048fe05f78a71fe9ddee799bd70f7586061fdd9a1390a894701eb96678ad9c332a21f2c2b079896924bee14d64ea89f6314babae1faac289d6eb -OpenBLAS.v0.3.13+6.i686-linux-musl-libgfortran5.tar.gz/md5/712e9c7ef4640dbc150371ef3a10e249 -OpenBLAS.v0.3.13+6.i686-linux-musl-libgfortran5.tar.gz/sha512/3407fab09ae6e2b12c2b586915557d121bfa345a4bf66597bec2d5850ce33ad70dddb45ad08a975097e2a428e65abffdbd9747f1b46fa944bc52218798fd2e34 -OpenBLAS.v0.3.13+6.i686-w64-mingw32-libgfortran3.tar.gz/md5/93d7254e1e03f4ef1acb6b4e8d63c813 -OpenBLAS.v0.3.13+6.i686-w64-mingw32-libgfortran3.tar.gz/sha512/198d4d0455f981345f20ff4a196cca056fbd7c5fd4d6a2b11e0ec6ba695c362d309947b9fcc13a6c51a44cc3ea73e559c0246a98b26fd6baa6cf07a055f5c972 -OpenBLAS.v0.3.13+6.i686-w64-mingw32-libgfortran4.tar.gz/md5/728d9f80b9e6b5ecce0ffab86b7e1c52 -OpenBLAS.v0.3.13+6.i686-w64-mingw32-libgfortran4.tar.gz/sha512/1b8fc2e3e14fb172ec7d99d5beef54bcabdc807318f1b0415f1bdf7bb97a1e49c20168a9bfc0e89f4f9367dfbd1011e3cffe74b515da53fce00f06896387ca72 -OpenBLAS.v0.3.13+6.i686-w64-mingw32-libgfortran5.tar.gz/md5/b989478ab0496a27daf87f8ebb396316 -OpenBLAS.v0.3.13+6.i686-w64-mingw32-libgfortran5.tar.gz/sha512/c56ae711ecc9c6fe9e65e7610011f7189ecda4c0e94cfdd6bb150a32eac6f3d2343c671005f4008873e2f026fa312ce0257716a47fb4e91f82a6d29013dfc303 -OpenBLAS.v0.3.13+6.powerpc64le-linux-gnu-libgfortran3.tar.gz/md5/194ec8e4078fc6624acfefb29a9a1177 -OpenBLAS.v0.3.13+6.powerpc64le-linux-gnu-libgfortran3.tar.gz/sha512/ecdd5b17232ae08e76f6822ec52cc96e4b5cde0748baf799799aa7946966b61f83c5b1d8a70e4f14b4e074e13e0cc72f2261f2a304ab8d8be15e68a004210be1 -OpenBLAS.v0.3.13+6.powerpc64le-linux-gnu-libgfortran4.tar.gz/md5/f08aad57a0d92ba7811b40deb7c40e5a -OpenBLAS.v0.3.13+6.powerpc64le-linux-gnu-libgfortran4.tar.gz/sha512/f5759dfce2854f929a73e11253edd37e100b9437829eca893f97a2c08a7ebc7af4815f588466cc8230985932f47b150e671d3a822e8463c1461bc3ce698f222d -OpenBLAS.v0.3.13+6.powerpc64le-linux-gnu-libgfortran5.tar.gz/md5/bf291c76d9c9642e6964141eb541e4e0 -OpenBLAS.v0.3.13+6.powerpc64le-linux-gnu-libgfortran5.tar.gz/sha512/0792f5d3c4c7f1ff5f43bcf6aafc8547c742e969ef4fc056f098649f7d99470538827349e5f39f0ce81ac15ec992f11d93a78f1ea9673a67ec076787b6d7b9c5 -OpenBLAS.v0.3.13+6.x86_64-apple-darwin-libgfortran3.tar.gz/md5/9a1979528b2b54df3012e2182b834bbd -OpenBLAS.v0.3.13+6.x86_64-apple-darwin-libgfortran3.tar.gz/sha512/1752e0ee45107eec916a42370e19b6091b41423eb0f9443f23f78c3e8dd8db5fa0b8b72f5edf2d26e759e0f44056034dde1bce38b9c12f58d6c931ec873bd67c -OpenBLAS.v0.3.13+6.x86_64-apple-darwin-libgfortran4.tar.gz/md5/1b30b010ee8ecf949d83d98be7cd59a0 -OpenBLAS.v0.3.13+6.x86_64-apple-darwin-libgfortran4.tar.gz/sha512/bab954ecbc2e9ece41807409bfef66063dc98cc7fbdbb0bbce24a331d5b121b0c63432a13cea935c5c27090f790e9fba599e1c129e0005656952805260732da6 -OpenBLAS.v0.3.13+6.x86_64-apple-darwin-libgfortran5.tar.gz/md5/da031443b1bd5ed8abb8e956a05c616c -OpenBLAS.v0.3.13+6.x86_64-apple-darwin-libgfortran5.tar.gz/sha512/0009d10265ff16603c8552663b3c71ab619905b18fe87119a3203fe24d531148b8b18f727260fc125362c58a6226d1dca98a6517e9b7a93418a2cdbb2c66806e -OpenBLAS.v0.3.13+6.x86_64-linux-gnu-libgfortran3.tar.gz/md5/133b638a2efa22381cd70abe871e6ebe -OpenBLAS.v0.3.13+6.x86_64-linux-gnu-libgfortran3.tar.gz/sha512/98067cbaf1f5cf4a6ba01cf09ec9de044c04007f3a1953e51a75439cfb7215caa5b1a7f1b848b216926231a9511c45e78ba78abd39da06c6fbec4ce9542890f2 -OpenBLAS.v0.3.13+6.x86_64-linux-gnu-libgfortran4.tar.gz/md5/3590e16f503a615a8c8886af39d3fd14 -OpenBLAS.v0.3.13+6.x86_64-linux-gnu-libgfortran4.tar.gz/sha512/b7f3fd487e44a4f6cbbf035bc9fb433aa761f05bc1cf0c5351e6f9a9e5b80450ffbd11f86f904477c89aadbe24e22780ce108e228585e701d92141a735b454fd -OpenBLAS.v0.3.13+6.x86_64-linux-gnu-libgfortran5.tar.gz/md5/05472a418ff1d7f6bedb58894d6f5356 -OpenBLAS.v0.3.13+6.x86_64-linux-gnu-libgfortran5.tar.gz/sha512/fc8a84b28db834b93a0c9a9c96ba22dfc6018cba90c0d43f4e1db7fcbda73c0aec04d7347db02b94df5375e785d447b3aeb993bf0ded69e5d43c2486c13b2aa5 -OpenBLAS.v0.3.13+6.x86_64-linux-musl-libgfortran3.tar.gz/md5/22200029744717079b3b8663d683273a -OpenBLAS.v0.3.13+6.x86_64-linux-musl-libgfortran3.tar.gz/sha512/664bc2e95f10ac5668d51a2ffae488ad002f00995e5e7b620dd894e816bcaeeb7ccffb45f448365484f97f7aa5ac7b237ca1767e2a9421fd5c5fa39098c9fcb4 -OpenBLAS.v0.3.13+6.x86_64-linux-musl-libgfortran4.tar.gz/md5/b9fb6101fa172dd0f1a00c07673b308e -OpenBLAS.v0.3.13+6.x86_64-linux-musl-libgfortran4.tar.gz/sha512/cf49792da8bc3e3a971b0361f2bdd835db46764c308d4ad0e20215c8bba5d6bd9b96e9e8fe2cdfb835bba4f21e62287f7b67245ff1d00a9ef3f9e44201b53412 -OpenBLAS.v0.3.13+6.x86_64-linux-musl-libgfortran5.tar.gz/md5/17c0ab204c65b252988bf873226f003d -OpenBLAS.v0.3.13+6.x86_64-linux-musl-libgfortran5.tar.gz/sha512/02f493a6cb20c51c38203928a5a9e4890fc9285ce1907a552b61bd96bc64bc50a1932236d7617e83edc5ae1c40da84cc1d8db80c190605676869a8d1a57c4d7e -OpenBLAS.v0.3.13+6.x86_64-unknown-freebsd-libgfortran3.tar.gz/md5/24e787f88452b2f304c269061ad07b0a -OpenBLAS.v0.3.13+6.x86_64-unknown-freebsd-libgfortran3.tar.gz/sha512/d45272120a6e15431b9a08afe5648afa903b588e2d65541f80ce123117dfc0e6d3b620ce4063211a420f1cfd398e969be69eb6a6302211fc368c4af3c9d6d3ef -OpenBLAS.v0.3.13+6.x86_64-unknown-freebsd-libgfortran4.tar.gz/md5/9aa8cd86c2de41ed2ed47bccc315f19f -OpenBLAS.v0.3.13+6.x86_64-unknown-freebsd-libgfortran4.tar.gz/sha512/1c42e55fef774a34d3b0e0b0f899418a501cc9d56c4d38cfa0b4823a7622c7eb594f4ab222bd6994ba1c1eb7b69a37b10ec78b206a24d54276b03f69133b7b40 -OpenBLAS.v0.3.13+6.x86_64-unknown-freebsd-libgfortran5.tar.gz/md5/e09d926e41b3a52188cac7efe9d9aeed -OpenBLAS.v0.3.13+6.x86_64-unknown-freebsd-libgfortran5.tar.gz/sha512/eddc11f4b5535e629af6fe2705f24b142e457fd7721d6f9892e1c951d2722e996f32a59d05df803bc7a77c15ae011cc5f36a88709a7ebc9e6be00cd52789083b -OpenBLAS.v0.3.13+6.x86_64-w64-mingw32-libgfortran3.tar.gz/md5/5f09322a961185e965f8914b87fb769c -OpenBLAS.v0.3.13+6.x86_64-w64-mingw32-libgfortran3.tar.gz/sha512/531860456a4604d7743b52632ca1562448e3b34015e0a7082935a12fe7537c3824fd6eca29813b8b28043c85db4c748ca2e42dfb443149e225b2ae1ebf641ece -OpenBLAS.v0.3.13+6.x86_64-w64-mingw32-libgfortran4.tar.gz/md5/68bf07ec07fab8eb000742f5b34a297a -OpenBLAS.v0.3.13+6.x86_64-w64-mingw32-libgfortran4.tar.gz/sha512/5cf754e09737a9ccf67998a0dd64a6eb836784489b337bd9cd3379773ccc0d8261f6eb91ae6811dc45f3dd13480c6e0abc603f13add94bc5505ed4aa41e82951 -OpenBLAS.v0.3.13+6.x86_64-w64-mingw32-libgfortran5.tar.gz/md5/d30d1b10c1a98ecbed686a1d133f4abc -OpenBLAS.v0.3.13+6.x86_64-w64-mingw32-libgfortran5.tar.gz/sha512/6a61cd1eb2b20f33bb6370d760cf98c8c3af2f323b3c83c866ab8d2e3010771da7345fccbbb94880ca0c0956b711d3127566f040bbb79166e281b9ea6d14b2c7 +OpenBLAS.v0.3.13+7.aarch64-apple-darwin-libgfortran5.tar.gz/md5/c9800f7e24105c92a5205c77ddbc4227 +OpenBLAS.v0.3.13+7.aarch64-apple-darwin-libgfortran5.tar.gz/sha512/43703203a6d7c7aff8c8a257a2f5393d930e7e12064ff9a7890114dc250c28f0c73d735c4bbe09a811610cec6f4fe5079a806fb5898025c92067239dc70d6f62 +OpenBLAS.v0.3.13+7.aarch64-linux-gnu-libgfortran3.tar.gz/md5/ffb49e047b54a68b9de82ac3ae64a94d +OpenBLAS.v0.3.13+7.aarch64-linux-gnu-libgfortran3.tar.gz/sha512/745f30477562ec0bcf754a36e0c0082a60afea518dbe9fc46f95ee7547c33eece8717f6c9ee54bf1420a221ab7fb779dd4ccc98ca74164315975b7ac8e8b6979 +OpenBLAS.v0.3.13+7.aarch64-linux-gnu-libgfortran4.tar.gz/md5/ccdd01f36e19f8269750c93901c54bf7 +OpenBLAS.v0.3.13+7.aarch64-linux-gnu-libgfortran4.tar.gz/sha512/ef619a6b5d140253a5f310f975d1aca378a8419f75b90713baf73aa1f3be9cdc43ae96a8fc40bc7d3502947bce87de4fd5d869f16220bde1ced4e6730437ea5e +OpenBLAS.v0.3.13+7.aarch64-linux-gnu-libgfortran5.tar.gz/md5/cbe589a28fa89287502eb591d26c0a1d +OpenBLAS.v0.3.13+7.aarch64-linux-gnu-libgfortran5.tar.gz/sha512/7d894dda5e3eb124e17dcaa6ca7b02e29177f2ac678e18b6e57f6ce34c654c0dafb81fe470e93a42fa4b63f904b2cee00139cc149c7868d3f70b69313242187b +OpenBLAS.v0.3.13+7.aarch64-linux-musl-libgfortran3.tar.gz/md5/ebf835b3264f4b63cedac8c10f65316c +OpenBLAS.v0.3.13+7.aarch64-linux-musl-libgfortran3.tar.gz/sha512/2de3869ae6505789ff2ebbc83672ddb4f7a3f1610a88040ac9407dbafd23b7a0bdf19328964f4d901e7389636564fefb82442a1bb89a0d18e4a6441267d886b3 +OpenBLAS.v0.3.13+7.aarch64-linux-musl-libgfortran4.tar.gz/md5/3d20fe5e4c37e40eafd2a07ac5b11cf8 +OpenBLAS.v0.3.13+7.aarch64-linux-musl-libgfortran4.tar.gz/sha512/9dadabace2cec1260b2a02b42102453fa4c7e832c89d5c4f06b8a58ead30c2d926e6f615da03016aec596324619d34b7e25dec88e1dfa9725e420fbf6397c0ca +OpenBLAS.v0.3.13+7.aarch64-linux-musl-libgfortran5.tar.gz/md5/53c4a96fb47aed019efc780d0e9e4929 +OpenBLAS.v0.3.13+7.aarch64-linux-musl-libgfortran5.tar.gz/sha512/2e3ebec1e64f29308d7e61e80ff95dd7ff45a7bf7696639f6b786990d4e183c5cb8357e65f16b9c98058ff8d197a3e1e7c355a304e56c644fbe8b321d8941988 +OpenBLAS.v0.3.13+7.armv6l-linux-gnueabihf-libgfortran3.tar.gz/md5/59142e0c7a6e50c27e084f10982402c2 +OpenBLAS.v0.3.13+7.armv6l-linux-gnueabihf-libgfortran3.tar.gz/sha512/4e45b9a7087840edaf515af3a9ad15f6d5c2cbdb8be244b9c65542f6f6526e5f82fcd0939070b35a19a8ec1ea7c8886c82070359d74924b90f210ab3026b1d24 +OpenBLAS.v0.3.13+7.armv6l-linux-gnueabihf-libgfortran4.tar.gz/md5/2c00dddb46cd74324c023d9cea5d12e0 +OpenBLAS.v0.3.13+7.armv6l-linux-gnueabihf-libgfortran4.tar.gz/sha512/e4b6b07016c59727be3cc01fbfe1ceb2fc19bbddf96bffbd8a0b8bbf10e30768a7d8ed04052cbc53093d8f6d6f8d57c0d05d6692ba456bb8aa31a0f736617d33 +OpenBLAS.v0.3.13+7.armv6l-linux-gnueabihf-libgfortran5.tar.gz/md5/d98b02bba19262ebb4a6eae0971e19a8 +OpenBLAS.v0.3.13+7.armv6l-linux-gnueabihf-libgfortran5.tar.gz/sha512/f73413a520bf204d9c369dbc910e0df4b72e583ab31a66e5e64ae31e93464d6f8cc114be7c9f15738c900fa8762905f2c9ce198c45426eab22b119ac8fc489d3 +OpenBLAS.v0.3.13+7.armv6l-linux-musleabihf-libgfortran3.tar.gz/md5/5e34312709f68e06783e890d94447646 +OpenBLAS.v0.3.13+7.armv6l-linux-musleabihf-libgfortran3.tar.gz/sha512/f127d0df4a0b4d91c810990108f0f3daf89373f29002249edd6225330bdc804a0a2282e05ab128b15ec58c75098213481e26bb0e9a5a2b642da9c43457b9f9f9 +OpenBLAS.v0.3.13+7.armv6l-linux-musleabihf-libgfortran4.tar.gz/md5/02d6189238fe4ef41e791f558324e32c +OpenBLAS.v0.3.13+7.armv6l-linux-musleabihf-libgfortran4.tar.gz/sha512/fd5d4c2f43c4e98f0c28afdc43f2dfc97123fbe723c577688acaab959e96980c14b0ae76d150807da1814f9ea55dbc21a9cce9454d52804ba815cf8026d17117 +OpenBLAS.v0.3.13+7.armv6l-linux-musleabihf-libgfortran5.tar.gz/md5/14d77e7332ed0949342a4b659ce98088 +OpenBLAS.v0.3.13+7.armv6l-linux-musleabihf-libgfortran5.tar.gz/sha512/354113f9877ecb04dbdbc105991ee20c58d9bd49d499ee476af87135fbd277c7729e909e528843b5fd4ae2f076996ea74284ad384fc06584882ea5fdfd7d4206 +OpenBLAS.v0.3.13+7.armv7l-linux-gnueabihf-libgfortran3.tar.gz/md5/b32a6caa13c26d964a456f440a2df0ee +OpenBLAS.v0.3.13+7.armv7l-linux-gnueabihf-libgfortran3.tar.gz/sha512/4b19666ca3a32c1a145f89eed063cafea2eb468cafc3b47168977749a8e484e124b5008c58d00d40e4c7ba1b09669d7499fe259bd43c88ed0d064c326c85dea9 +OpenBLAS.v0.3.13+7.armv7l-linux-gnueabihf-libgfortran4.tar.gz/md5/4b15013643544594e7a8a4948b9a4db3 +OpenBLAS.v0.3.13+7.armv7l-linux-gnueabihf-libgfortran4.tar.gz/sha512/2fd0e4d5ec22e3ef831a60909cbf803ba88e16b7ba12269cf22bd14808fb25dccad597e0690530b704dc971c681f1c075f3663f4d7cb05998835e584cb9779b8 +OpenBLAS.v0.3.13+7.armv7l-linux-gnueabihf-libgfortran5.tar.gz/md5/7217154630d07a83fa84cbaf298d84e2 +OpenBLAS.v0.3.13+7.armv7l-linux-gnueabihf-libgfortran5.tar.gz/sha512/a9cded7959ef98027e1da87127464ac930dec3ba9c198296bf8c64918d31a8fcdd92d4d74e3aad2f3aff02553959e141986870873e01a5302c67e7efacc33616 +OpenBLAS.v0.3.13+7.armv7l-linux-musleabihf-libgfortran3.tar.gz/md5/65f601ff699b51719aacc4a495be5b82 +OpenBLAS.v0.3.13+7.armv7l-linux-musleabihf-libgfortran3.tar.gz/sha512/c96e4fadf74eea0c74ccc7d57670222d6bc097ceecc38211a742bdaf8c48491266302a96a33317ab4e8e19669b41f3051c5ca409c076ae1993f5218fa30f2cd6 +OpenBLAS.v0.3.13+7.armv7l-linux-musleabihf-libgfortran4.tar.gz/md5/7d0f0e432a372ce94cd127153b8976ee +OpenBLAS.v0.3.13+7.armv7l-linux-musleabihf-libgfortran4.tar.gz/sha512/b017bb4ffe9caec8410c72a80c5307e81cbfe84e4c148f3f99ca774efd17b47378b24ce95cfe6df45e8ee890ff0c326d480fabfbac0e494e25f620e82fdbbb8e +OpenBLAS.v0.3.13+7.armv7l-linux-musleabihf-libgfortran5.tar.gz/md5/398c894c743c181b4edcffebb5d91340 +OpenBLAS.v0.3.13+7.armv7l-linux-musleabihf-libgfortran5.tar.gz/sha512/c4c7acae9dfb49252dab6a7d0217e8caa8df707da72fcab3dcb5ea6449e42effd1a9df18531e8077d91ad8fdb323482a7fa405eda1a4660f48e59927ef33f525 +OpenBLAS.v0.3.13+7.i686-linux-gnu-libgfortran3.tar.gz/md5/ac7f07c75d419712e4ddad380fda0177 +OpenBLAS.v0.3.13+7.i686-linux-gnu-libgfortran3.tar.gz/sha512/4522c5b5924ff976e58ee30bbd0bf933baa2f705e3d68a83aaeeabaa8cd4cacf41edf05612f4616052d78ce04e70d62a411f8e0cc7ab9ab3fbc56dbae2615b67 +OpenBLAS.v0.3.13+7.i686-linux-gnu-libgfortran4.tar.gz/md5/08254b64198705d5062db0526d6d8cde +OpenBLAS.v0.3.13+7.i686-linux-gnu-libgfortran4.tar.gz/sha512/5d8c1062f15b11066d7400811492b8e2e1c33150bda4b74d7f9d7cd64529f0c0b89d7a1a2e644dc321be18fd3e3ba7dff92fe597f3d42aad5d903c8b26fa0e87 +OpenBLAS.v0.3.13+7.i686-linux-gnu-libgfortran5.tar.gz/md5/5f610eff8a8e7b24868a2b915419d4a3 +OpenBLAS.v0.3.13+7.i686-linux-gnu-libgfortran5.tar.gz/sha512/8967a180b57ada258aea76a39b8c71b718314460eeef2bad1e407be0c60a54f04a0b733944feb036c5fd2d67a8f3761babef10530dd871006f7d7ba366b4c95b +OpenBLAS.v0.3.13+7.i686-linux-musl-libgfortran3.tar.gz/md5/1867e826c4cdc6b6964bf2e7be43671e +OpenBLAS.v0.3.13+7.i686-linux-musl-libgfortran3.tar.gz/sha512/c7e7206361a4ee379c40a483aae1dc5357b8ba77e561fbf961cd7269674705c83ba2b5b09891b4567a330f9621d5a7bc0c323c8ec9d2385222b4afb57e010f8e +OpenBLAS.v0.3.13+7.i686-linux-musl-libgfortran4.tar.gz/md5/5a4511b55512387315e42555a1f35222 +OpenBLAS.v0.3.13+7.i686-linux-musl-libgfortran4.tar.gz/sha512/3381a32dd47d7106a131f8e6be89675c29b8ff496336e8f4dbc5bac13df3b1de9bd03a2c027b94ee43d66f4cb8fcab1545327552ac45280252046072dde3ebd7 +OpenBLAS.v0.3.13+7.i686-linux-musl-libgfortran5.tar.gz/md5/9766d92bb2a0bc7376d42537c0bff642 +OpenBLAS.v0.3.13+7.i686-linux-musl-libgfortran5.tar.gz/sha512/34149b0ae5ab26d4b5ec9f5a8a981eae713e355248c56af0d71eeb2720cd4e453d96fb9e885a48c94389759f5e015536b7a21d9720c6b46b167e6bbbccc717aa +OpenBLAS.v0.3.13+7.i686-w64-mingw32-libgfortran3.tar.gz/md5/3e13fa70512da79cb19d15899e967e8b +OpenBLAS.v0.3.13+7.i686-w64-mingw32-libgfortran3.tar.gz/sha512/c4e99d0bcfd9de4ddcdbf819872257a91e45cd778c7bf927b6a3c69e24d555d6a757236b08113160790a4a8fe0a3b258c17c8d43386a0d9ecf926e4e542b9a5b +OpenBLAS.v0.3.13+7.i686-w64-mingw32-libgfortran4.tar.gz/md5/724db97fb05d2418325b84eff736b0d6 +OpenBLAS.v0.3.13+7.i686-w64-mingw32-libgfortran4.tar.gz/sha512/4869bc155e2c5bbca2ea6a0107a2b12e7d7ec226dfa5ab81c8f46751f5e2a9342127c0c8ed24731cbfa05904db319ffdd907b248b725043d8bd089e911cf6808 +OpenBLAS.v0.3.13+7.i686-w64-mingw32-libgfortran5.tar.gz/md5/4fd5c17e2432dfbf2fbf6930c9b08617 +OpenBLAS.v0.3.13+7.i686-w64-mingw32-libgfortran5.tar.gz/sha512/92c4b8b61d9d4dfc8cc60c05cc1a8663e2cc33f3e0683d562f723939697237cfaf3925eb903ec2b443e1a943260c91e04029e582f9f07f2b3655ee5ed9812dad +OpenBLAS.v0.3.13+7.powerpc64le-linux-gnu-libgfortran3.tar.gz/md5/6b509bdecd697472c5c96b947a3d016f +OpenBLAS.v0.3.13+7.powerpc64le-linux-gnu-libgfortran3.tar.gz/sha512/494b8fa97c383554edd62d04b985f2fe25f1365d149af041d1d2d9c617df0fe12fff271e21a3811205e05412229e2f55043876ba6b553f22a7616653928b1908 +OpenBLAS.v0.3.13+7.powerpc64le-linux-gnu-libgfortran4.tar.gz/md5/5be5d102fd4c0537403a0fa8266a95d2 +OpenBLAS.v0.3.13+7.powerpc64le-linux-gnu-libgfortran4.tar.gz/sha512/2fb952a7da419d64f41b5fdff7c49e8e750f8724348180b52e61a50b4b55e5a3c3d072455d3ce870fb240b9c50c6f4572f6211813edb965ca41fa27efc85de6a +OpenBLAS.v0.3.13+7.powerpc64le-linux-gnu-libgfortran5.tar.gz/md5/9bb7b2ac52789cd7eba17e4b564d95d8 +OpenBLAS.v0.3.13+7.powerpc64le-linux-gnu-libgfortran5.tar.gz/sha512/a50700ab72ab169c91bd10eccb4a03231d0e223bcf3e158331af4a6805e2f17ab042eb6c9db335a800ab5b69554c0b9a5aa78c1f112c8b579f5148013afa15c2 +OpenBLAS.v0.3.13+7.x86_64-apple-darwin-libgfortran3.tar.gz/md5/2bfd33949884b29e2621bd4db9ea790b +OpenBLAS.v0.3.13+7.x86_64-apple-darwin-libgfortran3.tar.gz/sha512/87e32e09c5fb6da7396a13646a19ddc9f0aa6070060fba1e4f4490fc447c041a0b6ae68cd338e1f1b2d610bf61e28274823c81ae229768d6825104337d82e3d5 +OpenBLAS.v0.3.13+7.x86_64-apple-darwin-libgfortran4.tar.gz/md5/e0a3f443cd840d5a9cca3748c0fd247b +OpenBLAS.v0.3.13+7.x86_64-apple-darwin-libgfortran4.tar.gz/sha512/b4a55211a2a64fceb2eb89c1bbb06a5f658d4d81dcc6c67c1fc6a804ba16de8a05c341b81bae8b14788b85f772555785696a2b11b1cb6873ab9fbd174eebf1c1 +OpenBLAS.v0.3.13+7.x86_64-apple-darwin-libgfortran5.tar.gz/md5/3acd992bd55a527ff96cbc1fd208300a +OpenBLAS.v0.3.13+7.x86_64-apple-darwin-libgfortran5.tar.gz/sha512/192300b6480efe523e3a196570743e3c091d9d29c6f16cb3f5f951b344e8ecc5a76f235c8fa2b2a9bd56c8dc394fca447c2bd1d4102ad7f9823ab71436154dbd +OpenBLAS.v0.3.13+7.x86_64-linux-gnu-libgfortran3.tar.gz/md5/35ede94f298e95ff772e3655692da81c +OpenBLAS.v0.3.13+7.x86_64-linux-gnu-libgfortran3.tar.gz/sha512/109fbc3ee23528640011df500f7843bec3f42d92b6be99e2101bfd0c6bb798d5c5a0c8a9d2567d11e50bdf54213347ea204c383660d2fd6445ae0735f210d211 +OpenBLAS.v0.3.13+7.x86_64-linux-gnu-libgfortran4.tar.gz/md5/5d97a16fb7ba45d34aee0d1b55f81008 +OpenBLAS.v0.3.13+7.x86_64-linux-gnu-libgfortran4.tar.gz/sha512/f957549494ec3c11fbb73cad4b43d8a39a7f0e509a3f797cd35898f40ed577aad27cc721a5720eb38e0ccd5064915a4ca93b67e517f7fa1cef86fbe3f88c2529 +OpenBLAS.v0.3.13+7.x86_64-linux-gnu-libgfortran5.tar.gz/md5/85903515954b13d71dfc1cfed5364000 +OpenBLAS.v0.3.13+7.x86_64-linux-gnu-libgfortran5.tar.gz/sha512/ee3fdeede35b52987565e55c96a1a47964cf1da52b25753302c2ac4671b2921a70656a5f9e39bf1b7db0d6037c305f66b4aa22529713239ca30c322f5c3d8f97 +OpenBLAS.v0.3.13+7.x86_64-linux-musl-libgfortran3.tar.gz/md5/b9a86f939ec7d76674d67653d3acdfee +OpenBLAS.v0.3.13+7.x86_64-linux-musl-libgfortran3.tar.gz/sha512/8a9d10605d9fad833ece78bc0c4690e43050e5e276b0c76ff194b617134e05261db2b385fe2c4b0b2313a3be107731b4cc71dae79d6e403e64a6ca635a3d4b47 +OpenBLAS.v0.3.13+7.x86_64-linux-musl-libgfortran4.tar.gz/md5/6a4a082c4d73cb6dad69460deb75afdd +OpenBLAS.v0.3.13+7.x86_64-linux-musl-libgfortran4.tar.gz/sha512/8fa8c2f07ff044acc78caaf7e34f6e299567ac82436059c70d9a149ffd03d0d257a009592f845e22554a17dbd59fb13c23582a0e4131a186139c9be9c71b9f2d +OpenBLAS.v0.3.13+7.x86_64-linux-musl-libgfortran5.tar.gz/md5/50148e4dc8881c9f1f4c2bc936c3f59e +OpenBLAS.v0.3.13+7.x86_64-linux-musl-libgfortran5.tar.gz/sha512/df0019201f71a12867deb872d3a3f7b3c07919bb779b3f3f5612d52f9c02bba1c19e230c81c8421e32b5cf1140dc388f1dfae3379c081cecb4a516f1d28a3788 +OpenBLAS.v0.3.13+7.x86_64-unknown-freebsd-libgfortran3.tar.gz/md5/87b58444e006bb680e8139b2ee7bc998 +OpenBLAS.v0.3.13+7.x86_64-unknown-freebsd-libgfortran3.tar.gz/sha512/c32638c812a3cc4e3c3916b6a9bf572ac202b2101946a18a7af89de1cd3171a44f9d9308a6de822bd703acd96533c963ad8a8205a1200039540191cd03fe1f6b +OpenBLAS.v0.3.13+7.x86_64-unknown-freebsd-libgfortran4.tar.gz/md5/f8a07c961fa2b6d268ff1b3f4e02b729 +OpenBLAS.v0.3.13+7.x86_64-unknown-freebsd-libgfortran4.tar.gz/sha512/b3faaa4155971047a8f58123da5dbf51cd6cac574a46e4a339b2be0570f1868fddbe9b46ce07f75fb561bb5da42bf19466035a05286832a85f1f39c58265bfb4 +OpenBLAS.v0.3.13+7.x86_64-unknown-freebsd-libgfortran5.tar.gz/md5/67d69caa1877b74ca652f0e96718ddde +OpenBLAS.v0.3.13+7.x86_64-unknown-freebsd-libgfortran5.tar.gz/sha512/bc72e2df6e0dec6962cd32b77f49ec93b05b34dbc95c0b0c31da6158d3a5f497f6321a895f3faa48c82ee956fbd8e82346bb8d8a20a9639e2e689f0b85ab5c2e +OpenBLAS.v0.3.13+7.x86_64-w64-mingw32-libgfortran3.tar.gz/md5/dc755ddb59511ef049daf85a38ef0804 +OpenBLAS.v0.3.13+7.x86_64-w64-mingw32-libgfortran3.tar.gz/sha512/fa5a559165b97cc5ca24d5df02dfeb1f97b8619512d8f99e3c8c8ee800aec0d3ca56ac4170569dafee7cec738e9abc5017958c153bd44d19d60fbecac53a0ee2 +OpenBLAS.v0.3.13+7.x86_64-w64-mingw32-libgfortran4.tar.gz/md5/ff56c35358fb846827f8f869fdca4b21 +OpenBLAS.v0.3.13+7.x86_64-w64-mingw32-libgfortran4.tar.gz/sha512/c8c0029c9b95f5a11dfc84bd02b944ed96de5c96835b2e6dc5e8c401fc37b667f8ea956f3715794b01be68ea86e0c74b4ebd22f728d1f9777516bfdca944c1b3 +OpenBLAS.v0.3.13+7.x86_64-w64-mingw32-libgfortran5.tar.gz/md5/e5bbc60da2dce3c4abe0583cff4b985e +OpenBLAS.v0.3.13+7.x86_64-w64-mingw32-libgfortran5.tar.gz/sha512/344dac288566886013b59c40877b879578b11f57b90433e65909b56b7e06416c0ceffedf08cc3d05e08514a098309ae492fd57c30dc97737cdede1aebed2ea2d diff --git a/deps/openblas.mk b/deps/openblas.mk index a1ce15100ac4c4..ee6712d883de63 100644 --- a/deps/openblas.mk +++ b/deps/openblas.mk @@ -118,7 +118,12 @@ $(BUILDDIR)/$(OPENBLAS_SRC_DIR)/openblas-Only-filter-out-mavx-on-Sandybridge.pat patch -p1 -f < $(SRCDIR)/patches/openblas-Only-filter-out-mavx-on-Sandybridge.patch echo 1 > $@ -$(BUILDDIR)/$(OPENBLAS_SRC_DIR)/build-configured: $(BUILDDIR)/$(OPENBLAS_SRC_DIR)/openblas-Only-filter-out-mavx-on-Sandybridge.patch-applied +$(BUILDDIR)/$(OPENBLAS_SRC_DIR)/openblas-armv8-volatile-detecion.patch-applied: $(BUILDDIR)/$(OPENBLAS_SRC_DIR)/openblas-Only-filter-out-mavx-on-Sandybridge.patch-applied + cd $(BUILDDIR)/$(OPENBLAS_SRC_DIR) && \ + patch -p1 -f < $(SRCDIR)/patches/openblas-armv8-volatile-detecion.patch + echo 1 > $@ + +$(BUILDDIR)/$(OPENBLAS_SRC_DIR)/build-configured: $(BUILDDIR)/$(OPENBLAS_SRC_DIR)/openblas-armv8-volatile-detecion.patch-applied echo 1 > $@ $(BUILDDIR)/$(OPENBLAS_SRC_DIR)/build-compiled: $(BUILDDIR)/$(OPENBLAS_SRC_DIR)/build-configured diff --git a/deps/patches/openblas-armv8-volatile-detecion.patch b/deps/patches/openblas-armv8-volatile-detecion.patch new file mode 100644 index 00000000000000..f1fb36b6a34ab4 --- /dev/null +++ b/deps/patches/openblas-armv8-volatile-detecion.patch @@ -0,0 +1,23 @@ +From 6fe0f1fab9d6a7f46d71d37ebb210fbf56924fbc Mon Sep 17 00:00:00 2001 +From: Martin Kroeker +Date: Mon, 11 Jan 2021 19:05:29 +0100 +Subject: [PATCH] Label get_cpu_ftr as volatile to keep gcc from rearranging + the code + +--- + driver/others/dynamic_arm64.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/driver/others/dynamic_arm64.c b/driver/others/dynamic_arm64.c +index 4f1b12f27a..37c0694b6f 100644 +--- a/driver/others/dynamic_arm64.c ++++ b/driver/others/dynamic_arm64.c +@@ -68,7 +68,7 @@ extern void openblas_warning(int verbose, const char * msg); + #endif + + #define get_cpu_ftr(id, var) ({ \ +- __asm__("mrs %0, "#id : "=r" (var)); \ ++ __asm__ __volatile__("mrs %0, "#id : "=r" (var)); \ + }) + + static char *corename[] = { diff --git a/stdlib/OpenBLAS_jll/Project.toml b/stdlib/OpenBLAS_jll/Project.toml index a879e204dcb3f8..4be6814c6632ef 100644 --- a/stdlib/OpenBLAS_jll/Project.toml +++ b/stdlib/OpenBLAS_jll/Project.toml @@ -1,6 +1,6 @@ name = "OpenBLAS_jll" uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" -version = "0.3.13+6" +version = "0.3.13+7" [deps] CompilerSupportLibraries_jll = "e66e0078-7015-5450-92f7-15fbd957f2ae" From c2b4b382c11b5668cb9091138b1fa9178c47bff5 Mon Sep 17 00:00:00 2001 From: Simeon Schaub Date: Tue, 10 Aug 2021 13:09:54 +0200 Subject: [PATCH 039/135] [IRShow] expose index information to postprinter (#41828) I am experimenting with showing some other information besides just the types here as well and I think this would be generally useful. This passes that information as an `IOContext` as to not break any downstream uses of this code. --- base/compiler/ssair/show.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/base/compiler/ssair/show.jl b/base/compiler/ssair/show.jl index ba3a637f61e935..4174267ec5a5ee 100644 --- a/base/compiler/ssair/show.jl +++ b/base/compiler/ssair/show.jl @@ -628,7 +628,7 @@ function show_ir_stmt(io::IO, code::Union{IRCode, CodeInfo}, idx::Int, line_info if new_node_type === UNDEF # try to be robust against errors printstyled(io, "::#UNDEF", color=:red) elseif show_type - line_info_postprinter(io, new_node_type, node_idx in used) + line_info_postprinter(IOContext(io, :idx => node_idx), new_node_type, node_idx in used) end println(io) i += 1 @@ -643,7 +643,7 @@ function show_ir_stmt(io::IO, code::Union{IRCode, CodeInfo}, idx::Int, line_info # This is an error, but can happen if passes don't update their type information printstyled(io, "::#UNDEF", color=:red) elseif show_type - line_info_postprinter(io, type, idx in used) + line_info_postprinter(IOContext(io, :idx => idx), type, idx in used) end end println(io) From 34dc0449ce5d6ffa1a936b38a64e3d1590ffff80 Mon Sep 17 00:00:00 2001 From: Dilum Aluthge Date: Tue, 10 Aug 2021 13:33:04 -0400 Subject: [PATCH 040/135] CI (Buildbot, GHA): Simplify the `permissions` key in the workflow file for the "Statuses" workflow (#41851) --- .github/workflows/statuses.yml | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/.github/workflows/statuses.yml b/.github/workflows/statuses.yml index df86caa3acee30..97ec290abe0130 100644 --- a/.github/workflows/statuses.yml +++ b/.github/workflows/statuses.yml @@ -30,17 +30,7 @@ on: # These are the permissions for the `GITHUB_TOKEN` token. # We should only give the token the minimum necessary set of permissions. permissions: - statuses: write - actions: none - checks: none - contents: none - deployments: none - issues: none - discussions: none - packages: none - pull-requests: none - repository-projects: none - security-events: none + statuses: write jobs: statuses: From 41ce35d125711a975ce7f3d0be356ac3726a6e7a Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Tue, 10 Aug 2021 17:30:43 -0400 Subject: [PATCH 041/135] codegen: fix emission criteria for some special functions (#41813) We depend on taking the address of these functions to support unwinding properly, particularly on Win64. Fixes #41750 --- src/codegen.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index ba583799e1c975..c68c5dc24eb8c6 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -4977,7 +4977,7 @@ static Function *emit_tojlinvoke(jl_code_instance_t *codeinst, Module *M, jl_cod std::string name; raw_string_ostream(name) << "tojlinvoke" << globalUnique++; Function *f = Function::Create(jl_func_sig, - GlobalVariable::PrivateLinkage, + GlobalVariable::InternalLinkage, name, M); jl_init_function(f); f->addFnAttr(Thunk); @@ -7539,8 +7539,8 @@ static std::pair, jl_llvm_functions_t> JL_UNLOCK(&m->writelock); } - // link the dependent llvmcall modules, but switch their function's linkage to private - // so that they don't show up in the execution engine. + // link the dependent llvmcall modules, but switch their function's linkage to internal + // so that they don't conflict when they show up in the execution engine. for (auto &Mod : ctx.llvmcall_modules) { SmallVector Exports; for (const auto &F: Mod->functions()) @@ -7550,7 +7550,7 @@ static std::pair, jl_llvm_functions_t> jl_error("Failed to link LLVM bitcode"); } for (auto FN: Exports) - jl_Module->getFunction(FN)->setLinkage(GlobalVariable::PrivateLinkage); + jl_Module->getFunction(FN)->setLinkage(GlobalVariable::InternalLinkage); } // link in opaque closure modules @@ -7561,7 +7561,7 @@ static std::pair, jl_llvm_functions_t> Exports.push_back(F.getName().str()); jl_merge_module(jl_Module, std::move(Mod)); for (auto FN: Exports) - jl_Module->getFunction(FN)->setLinkage(GlobalVariable::PrivateLinkage); + jl_Module->getFunction(FN)->setLinkage(GlobalVariable::InternalLinkage); } JL_GC_POP(); @@ -7759,9 +7759,9 @@ void jl_compile_workqueue( if (!preal_specsig) { // emit specsig-to-(jl)invoke conversion Function *preal = emit_tojlinvoke(codeinst, mod, params); - protodecl->setLinkage(GlobalVariable::PrivateLinkage); + protodecl->setLinkage(GlobalVariable::InternalLinkage); //protodecl->setAlwaysInline(); - protodecl->addFnAttr("no-frame-pointer-elim", "true"); + jl_init_function(protodecl); size_t nrealargs = jl_nparams(codeinst->def->specTypes); // number of actual arguments being passed // TODO: maybe this can be cached in codeinst->specfptr? emit_cfunc_invalidate(protodecl, proto_cc, proto_return_roots, codeinst->def->specTypes, codeinst->rettype, nrealargs, params, preal); From 2d8174254805b96ce936f233ce75264ad18051cf Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Tue, 10 Aug 2021 17:31:22 -0400 Subject: [PATCH 042/135] win: fix lock function call for backtrace collection (#41849) Avoids an assert when this is triggered --- src/signals-win.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/signals-win.c b/src/signals-win.c index 984330dc434dc1..5d1a963078df46 100644 --- a/src/signals-win.c +++ b/src/signals-win.c @@ -141,7 +141,7 @@ void jl_throw_in_ctx(jl_value_t *excpt, PCONTEXT ctxThread) ct->gcstack); } else if (have_backtrace_fiber) { - JL_LOCK(&backtrace_lock); + JL_LOCK_NOGC(&backtrace_lock); stkerror_ctx = ctxThread; stkerror_ptls = ptls; jl_swapcontext(&error_return_fiber, &collect_backtrace_fiber); From cc3fc0b27b4793b231ea537795cc5f3fbff7dbc2 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Tue, 10 Aug 2021 17:31:58 -0400 Subject: [PATCH 043/135] atomics: switch to using exact types for return pairs (#41659) This makes many more functions type-stable, by directly preserving the element type when making the copy, and prints as `old => new`, like the argument to atomic replace. For replace, we use Pair{FT, FT} (like the argument). For modify, we use NamedTuple{(:old, :success), Tuple{FT, Bool}}. --- base/Base.jl | 3 ++ base/boot.jl | 14 ++++++++- base/compiler/tfuncs.jl | 64 ++++++++++++++++++++++++++++++--------- base/expr.jl | 12 ++++---- base/pair.jl | 13 -------- src/cgutils.cpp | 17 +++++------ src/codegen.cpp | 1 + src/datatype.c | 47 ++++++++++++---------------- src/gc.c | 3 ++ src/init.c | 1 + src/jl_exported_data.inc | 1 + src/jl_exported_funcs.inc | 2 ++ src/jltypes.c | 44 +++++++++++++++++++++------ src/julia.h | 5 ++- src/runtime_intrinsics.c | 27 ++++++++++------- src/staticdata.c | 3 +- test/atomics.jl | 60 +++++++++++++++++++----------------- test/intrinsics.jl | 24 ++++++++------- test/show.jl | 2 +- 19 files changed, 209 insertions(+), 134 deletions(-) diff --git a/base/Base.jl b/base/Base.jl index 42a506479326b9..09fdcb1689de37 100644 --- a/base/Base.jl +++ b/base/Base.jl @@ -107,6 +107,9 @@ include("options.jl") include("promotion.jl") include("tuple.jl") include("expr.jl") +Pair{A, B}(@nospecialize(a), @nospecialize(b)) where {A, B} = (@_inline_meta; Pair{A, B}(convert(A, a)::A, convert(B, b)::B)) +#Pair{Any, B}(@nospecialize(a::Any), b) where {B} = (@_inline_meta; Pair{Any, B}(a, Base.convert(B, b)::B)) +#Pair{A, Any}(a, @nospecialize(b::Any)) where {A} = (@_inline_meta; Pair{A, Any}(Base.convert(A, a)::A, b)) include("pair.jl") include("traits.jl") include("range.jl") diff --git a/base/boot.jl b/base/boot.jl index 98b8cf2e9cf40e..af66e471ae1d0e 100644 --- a/base/boot.jl +++ b/base/boot.jl @@ -171,7 +171,7 @@ export # key types Any, DataType, Vararg, NTuple, Tuple, Type, UnionAll, TypeVar, Union, Nothing, Cvoid, - AbstractArray, DenseArray, NamedTuple, + AbstractArray, DenseArray, NamedTuple, Pair, # special objects Function, Method, Module, Symbol, Task, Array, UndefInitializer, undef, WeakRef, VecElement, @@ -813,4 +813,16 @@ _parse = nothing # support for deprecated uses of internal _apply function _apply(x...) = Core._apply_iterate(Main.Base.iterate, x...) +struct Pair{A, B} + first::A + second::B + # if we didn't inline this, it's probably because the callsite was actually dynamic + # to avoid potentially compiling many copies of this, we mark the arguments with `@nospecialize` + # but also mark the whole function with `@inline` to ensure we will inline it whenever possible + # (even if `convert(::Type{A}, a::A)` for some reason was expensive) + Pair(a, b) = new{typeof(a), typeof(b)}(a, b) + Pair{A, B}(a::A, b::B) where {A, B} = new(a, b) + Pair{Any, Any}(@nospecialize(a::Any), @nospecialize(b::Any)) = new(a, b) +end + ccall(:jl_set_istopmod, Cvoid, (Any, Bool), Core, true) diff --git a/base/compiler/tfuncs.jl b/base/compiler/tfuncs.jl index 772db09417393f..b7d280cc15c1b7 100644 --- a/base/compiler/tfuncs.jl +++ b/base/compiler/tfuncs.jl @@ -466,29 +466,51 @@ add_tfunc(Core._typevar, 3, 3, typevar_tfunc, 100) add_tfunc(applicable, 1, INT_INF, (@nospecialize(f), args...)->Bool, 100) add_tfunc(Core.Intrinsics.arraylen, 1, 1, @nospecialize(x)->Int, 4) add_tfunc(arraysize, 2, 2, (@nospecialize(a), @nospecialize(d))->Int, 4) + function pointer_eltype(@nospecialize(ptr)) a = widenconst(ptr) - if a <: Ptr - if isa(a, DataType) && isa(a.parameters[1], Type) - return a.parameters[1] - elseif isa(a, UnionAll) && !has_free_typevars(a) - unw = unwrap_unionall(a) - if isa(unw, DataType) - return rewrap_unionall(unw.parameters[1], a) - end + if !has_free_typevars(a) + unw = unwrap_unionall(a) + if isa(unw, DataType) && unw.name === Ptr.body.name + T = unw.parameters[1] + T isa Type && return rewrap_unionall(T, a) end end return Any end +function atomic_pointermodify_tfunc(ptr, op, v, order) + @nospecialize + a = widenconst(ptr) + if !has_free_typevars(a) + unw = unwrap_unionall(a) + if isa(unw, DataType) && unw.name === Ptr.body.name + T = unw.parameters[1] + # note: we could sometimes refine this to a PartialStruct if we analyzed `op(T, T)::T` + T isa Type && return rewrap_unionall(Pair{T, T}, a) + end + end + return Pair +end +function atomic_pointerreplace_tfunc(ptr, x, v, success_order, failure_order) + @nospecialize + a = widenconst(ptr) + if !has_free_typevars(a) + unw = unwrap_unionall(a) + if isa(unw, DataType) && unw.name === Ptr.body.name + T = unw.parameters[1] + T isa Type && return rewrap_unionall(ccall(:jl_apply_cmpswap_type, Any, (Any,), T), a) + end + end + return ccall(:jl_apply_cmpswap_type, Any, (Any,), T) where T +end add_tfunc(pointerref, 3, 3, (a, i, align) -> (@nospecialize; pointer_eltype(a)), 4) add_tfunc(pointerset, 4, 4, (a, v, i, align) -> (@nospecialize; a), 5) - add_tfunc(atomic_fence, 1, 1, (order) -> (@nospecialize; Nothing), 4) add_tfunc(atomic_pointerref, 2, 2, (a, order) -> (@nospecialize; pointer_eltype(a)), 4) add_tfunc(atomic_pointerset, 3, 3, (a, v, order) -> (@nospecialize; a), 5) add_tfunc(atomic_pointerswap, 3, 3, (a, v, order) -> (@nospecialize; pointer_eltype(a)), 5) -add_tfunc(atomic_pointermodify, 4, 4, (a, op, v, order) -> (@nospecialize; T = pointer_eltype(a); Tuple{T, T}), 5) -add_tfunc(atomic_pointerreplace, 5, 5, (a, x, v, success_order, failure_order) -> (@nospecialize; Tuple{pointer_eltype(a), Bool}), 5) +add_tfunc(atomic_pointermodify, 4, 4, atomic_pointermodify_tfunc, 5) +add_tfunc(atomic_pointerreplace, 5, 5, atomic_pointerreplace_tfunc, 5) # more accurate typeof_tfunc for vararg tuples abstract only in length function typeof_concrete_vararg(t::DataType) @@ -911,11 +933,25 @@ setfield!_tfunc(o, f, v) = (@nospecialize; v) swapfield!_tfunc(o, f, v, order) = (@nospecialize; getfield_tfunc(o, f)) swapfield!_tfunc(o, f, v) = (@nospecialize; getfield_tfunc(o, f)) -modifyfield!_tfunc(o, f, op, v, order) = (@nospecialize; T = getfield_tfunc(o, f); T === Bottom ? T : Tuple{T, T}) -modifyfield!_tfunc(o, f, op, v) = (@nospecialize; T = getfield_tfunc(o, f); T === Bottom ? T : Tuple{T, T}) # TODO: also model op(o.f, v) call +modifyfield!_tfunc(o, f, op, v, order) = (@nospecialize; modifyfield!_tfunc(o, f, op, v)) +function modifyfield!_tfunc(o, f, op, v) + @nospecialize + T = _fieldtype_tfunc(o, isconcretetype(o), f) + T === Bottom && return Bottom + # note: we could sometimes refine this to a PartialStruct if we analyzed `op(o.f, v)::T` + PT = Const(Pair) + return instanceof_tfunc(apply_type_tfunc(PT, T, T))[1] +end replacefield!_tfunc(o, f, x, v, success_order, failure_order) = (@nospecialize; replacefield!_tfunc(o, f, x, v)) replacefield!_tfunc(o, f, x, v, success_order) = (@nospecialize; replacefield!_tfunc(o, f, x, v)) -replacefield!_tfunc(o, f, x, v) = (@nospecialize; T = getfield_tfunc(o, f); T === Bottom ? T : Tuple{widenconst(T), Bool}) +function replacefield!_tfunc(o, f, x, v) + @nospecialize + T = _fieldtype_tfunc(o, isconcretetype(o), f) + T === Bottom && return Bottom + PT = Const(ccall(:jl_apply_cmpswap_type, Any, (Any,), T) where T) + return instanceof_tfunc(apply_type_tfunc(PT, T))[1] +end + # we could use tuple_tfunc instead of widenconst, but `o` is mutable, so that is unlikely to be beneficial add_tfunc(getfield, 2, 4, getfield_tfunc, 1) diff --git a/base/expr.jl b/base/expr.jl index 9df363714679ef..e0304f7f7382bb 100644 --- a/base/expr.jl +++ b/base/expr.jl @@ -523,16 +523,16 @@ julia> @atomic a.x += 1 # increment field x of a, with sequential consistency 3 julia> @atomic a.x + 1 # increment field x of a, with sequential consistency -(3, 4) +3 => 4 julia> @atomic a.x # fetch field x of a, with sequential consistency 4 julia> @atomic max(a.x, 10) # change field x of a to the max value, with sequential consistency -(4, 10) +4 => 10 julia> @atomic a.x max 5 # again change field x of a to the max value, with sequential consistency -(10, 10) +10 => 10 ``` """ macro atomic(ex) @@ -653,18 +653,18 @@ julia> a = Atomic(1) Atomic{Int64}(1) julia> @atomicreplace a.x 1 => 2 # replace field x of a with 2 if it was 1, with sequential consistency -(1, true) +(old = 1, success = true) julia> @atomic a.x # fetch field x of a, with sequential consistency 2 julia> @atomicreplace a.x 1 => 2 # replace field x of a with 2 if it was 1, with sequential consistency -(2, false) +(old = 2, success = false) julia> xchg = 2 => 0; # replace field x of a with 0 if it was 1, with sequential consistency julia> @atomicreplace a.x xchg -(2, true) +(old = 2, success = true) julia> @atomic a.x # fetch field x of a, with sequential consistency 0 diff --git a/base/pair.jl b/base/pair.jl index 7481d50b7458b4..b5dffbb4e7e866 100644 --- a/base/pair.jl +++ b/base/pair.jl @@ -1,18 +1,5 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -struct Pair{A, B} - first::A - second::B - function Pair{A, B}(@nospecialize(a), @nospecialize(b)) where {A, B} - @_inline_meta - # if we didn't inline this, it's probably because the callsite was actually dynamic - # to avoid potentially compiling many copies of this, we mark the arguments with `@nospecialize` - # but also mark the whole function with `@inline` to ensure we will inline it whenever possible - # (even if `convert(::Type{A}, a::A)` for some reason was expensive) - return new(a, b) - end -end -Pair(a, b) = Pair{typeof(a), typeof(b)}(a, b) const => = Pair """ diff --git a/src/cgutils.cpp b/src/cgutils.cpp index 94ac4c071770e4..a453393bbd2cc3 100644 --- a/src/cgutils.cpp +++ b/src/cgutils.cpp @@ -1560,9 +1560,8 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx, 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); + jl_datatype_t *rettyp = jl_apply_cmpswap_type(jltype); + return emit_new_struct(ctx, (jl_value_t*)rettyp, 2, argv); } else { return ghostValue(jltype); @@ -1803,10 +1802,10 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx, } oldval = mark_julia_type(ctx, instr, isboxed, jltype); if (isreplacefield) { - // TODO: do better here + Success = ctx.builder.CreateZExt(Success, T_int8); jl_cgval_t argv[2] = {oldval, mark_julia_type(ctx, Success, false, jl_bool_type)}; - instr = emit_jlcall(ctx, jltuple_func, V_rnull, argv, 2, JLCALL_F_CC); - oldval = mark_julia_type(ctx, instr, true, jl_any_type); + jl_datatype_t *rettyp = jl_apply_cmpswap_type(jltype); + oldval = emit_new_struct(ctx, (jl_value_t*)rettyp, 2, argv); } } return oldval; @@ -3247,10 +3246,10 @@ static jl_cgval_t emit_setfield(jl_codectx_t &ctx, if (needlock) emit_lockstate_value(ctx, strct, false); if (isreplacefield) { + Success = ctx.builder.CreateZExt(Success, T_int8); 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); + jl_datatype_t *rettyp = jl_apply_cmpswap_type(jfty); + oldval = emit_new_struct(ctx, (jl_value_t*)rettyp, 2, argv); } return oldval; } diff --git a/src/codegen.cpp b/src/codegen.cpp index c68c5dc24eb8c6..d05080ee4216e9 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -1170,6 +1170,7 @@ static CallInst *emit_jlcall(jl_codectx_t &ctx, JuliaFunction *theFptr, Value *t jl_cgval_t *args, size_t nargs, CallingConv::ID cc); static Value *emit_f_is(jl_codectx_t &ctx, const jl_cgval_t &arg1, const jl_cgval_t &arg2, Value *nullcheck1 = nullptr, Value *nullcheck2 = nullptr); +static jl_cgval_t emit_new_struct(jl_codectx_t &ctx, jl_value_t *ty, size_t nargs, const jl_cgval_t *argv); static Value *literal_pointer_val(jl_codectx_t &ctx, jl_value_t *p); static GlobalVariable *prepare_global_in(Module *M, GlobalVariable *G); diff --git a/src/datatype.c b/src/datatype.c index 1a3ffa78170ac6..aecbe6f407ae61 100644 --- a/src/datatype.c +++ b/src/datatype.c @@ -953,18 +953,13 @@ JL_DLLEXPORT int jl_atomic_bool_cmpswap_bits(char *dst, const jl_value_t *expect return success; } -JL_DLLEXPORT jl_value_t *jl_atomic_cmpswap_bits(jl_datatype_t *dt, char *dst, const jl_value_t *expected, const jl_value_t *src, int nb) +JL_DLLEXPORT jl_value_t *jl_atomic_cmpswap_bits(jl_datatype_t *dt, jl_datatype_t *rettyp, char *dst, const jl_value_t *expected, const jl_value_t *src, int nb) { // dst must have the required alignment for an atomic of the given size // n.b.: this does not spuriously fail if there are padding bits - jl_value_t *params[2]; - params[0] = (jl_value_t*)dt; - params[1] = (jl_value_t*)jl_bool_type; - jl_datatype_t *tuptyp = jl_apply_tuple_type_v(params, 2); - JL_GC_PROMISE_ROOTED(tuptyp); // (JL_ALWAYS_LEAFTYPE) - int isptr = jl_field_isptr(tuptyp, 0); jl_task_t *ct = jl_current_task; - jl_value_t *y = jl_gc_alloc(ct->ptls, isptr ? nb : tuptyp->size, isptr ? dt : tuptyp); + int isptr = jl_field_isptr(rettyp, 0); + jl_value_t *y = jl_gc_alloc(ct->ptls, isptr ? nb : rettyp->size, isptr ? dt : rettyp); int success; jl_datatype_t *et = (jl_datatype_t*)jl_typeof(expected); if (nb == 0) { @@ -1053,7 +1048,7 @@ JL_DLLEXPORT jl_value_t *jl_atomic_cmpswap_bits(jl_datatype_t *dt, char *dst, co } if (isptr) { JL_GC_PUSH1(&y); - jl_value_t *z = jl_gc_alloc(ct->ptls, tuptyp->size, tuptyp); + jl_value_t *z = jl_gc_alloc(ct->ptls, rettyp->size, rettyp); *(jl_value_t**)z = y; JL_GC_POP(); y = z; @@ -1658,8 +1653,11 @@ jl_value_t *modify_nth_field(jl_datatype_t *st, jl_value_t *v, size_t i, jl_valu args[0] = r; jl_gc_safepoint(); } - // args[0] == r (old); args[1] == y (new) - args[0] = jl_f_tuple(NULL, args, 2); + // args[0] == r (old) + // args[1] == y (new) + jl_datatype_t *rettyp = jl_apply_modify_type(ty); + JL_GC_PROMISE_ROOTED(rettyp); // (JL_ALWAYS_LEAFTYPE) + args[0] = jl_new_struct(rettyp, args[0], args[1]); JL_GC_POP(); return args[0]; } @@ -1671,6 +1669,8 @@ jl_value_t *replace_nth_field(jl_datatype_t *st, jl_value_t *v, size_t i, jl_val jl_type_error("replacefield!", ty, rhs); size_t offs = jl_field_offset(st, i); jl_value_t *r = expected; + jl_datatype_t *rettyp = jl_apply_cmpswap_type(ty); + JL_GC_PROMISE_ROOTED(rettyp); // (JL_ALWAYS_LEAFTYPE) if (jl_field_isptr(st, i)) { jl_value_t **p = (jl_value_t**)((char*)v + offs); int success; @@ -1683,11 +1683,8 @@ jl_value_t *replace_nth_field(jl_datatype_t *st, jl_value_t *v, size_t i, jl_val if (success || !jl_egal(r, expected)) break; } - jl_value_t **args; - JL_GC_PUSHARGS(args, 2); - args[0] = r; - args[1] = success ? jl_true : jl_false; - r = jl_f_tuple(NULL, args, 2); + JL_GC_PUSH1(&r); + r = jl_new_struct(rettyp, r, success ? jl_true : jl_false); JL_GC_POP(); } else { @@ -1695,7 +1692,7 @@ jl_value_t *replace_nth_field(jl_datatype_t *st, jl_value_t *v, size_t i, jl_val int isunion = jl_is_uniontype(ty); int needlock; jl_value_t *rty = ty; - size_t fsz; + size_t fsz = jl_field_size(st, i); if (isunion) { assert(!isatomic); hasptr = 0; @@ -1708,7 +1705,7 @@ jl_value_t *replace_nth_field(jl_datatype_t *st, jl_value_t *v, size_t i, jl_val needlock = (isatomic && fsz > MAX_ATOMIC_SIZE); } if (isatomic && !needlock) { - r = jl_atomic_cmpswap_bits((jl_datatype_t*)rty, (char*)v + offs, r, rhs, fsz); + r = jl_atomic_cmpswap_bits((jl_datatype_t*)ty, rettyp, (char*)v + offs, r, rhs, fsz); int success = *((uint8_t*)r + fsz); if (success && hasptr) jl_gc_multi_wb(v, rhs); // rhs is immutable @@ -1717,23 +1714,17 @@ jl_value_t *replace_nth_field(jl_datatype_t *st, jl_value_t *v, size_t i, jl_val jl_task_t *ct = jl_current_task; uint8_t *psel; if (isunion) { - size_t fsz = jl_field_size(st, i); psel = &((uint8_t*)v)[offs + fsz - 1]; rty = jl_nth_union_component(rty, *psel); } - jl_value_t *params[2]; - params[0] = rty; - params[1] = (jl_value_t*)jl_bool_type; - jl_datatype_t *tuptyp = jl_apply_tuple_type_v(params, 2); - JL_GC_PROMISE_ROOTED(tuptyp); // (JL_ALWAYS_LEAFTYPE) - assert(!jl_field_isptr(tuptyp, 0)); - r = jl_gc_alloc(ct->ptls, tuptyp->size, (jl_value_t*)tuptyp); + assert(!jl_field_isptr(rettyp, 0)); + r = jl_gc_alloc(ct->ptls, rettyp->size, (jl_value_t*)rettyp); int success = (rty == jl_typeof(expected)); if (needlock) jl_lock_value(v); - size_t fsz = jl_datatype_size((jl_datatype_t*)rty); // need to shrink-wrap the final copy - memcpy((char*)r, (char*)v + offs, fsz); + memcpy((char*)r, (char*)v + offs, fsz); // copy field, including union bits if (success) { + size_t fsz = jl_datatype_size((jl_datatype_t*)rty); // need to shrink-wrap the final copy if (((jl_datatype_t*)rty)->layout->haspadding) success = jl_egal__bits(r, expected, (jl_datatype_t*)rty); else diff --git a/src/gc.c b/src/gc.c index f923b826de544d..91e4879f9bb935 100644 --- a/src/gc.c +++ b/src/gc.c @@ -2780,6 +2780,7 @@ static void jl_gc_queue_thread_local(jl_gc_mark_cache_t *gc_cache, jl_gc_mark_sp } void jl_gc_mark_enqueued_tasks(jl_gc_mark_cache_t *gc_cache, jl_gc_mark_sp_t *sp); +extern jl_value_t *cmpswap_names JL_GLOBALLY_ROOTED; // mark the initial root set static void mark_roots(jl_gc_mark_cache_t *gc_cache, jl_gc_mark_sp_t *sp) @@ -2811,6 +2812,8 @@ static void mark_roots(jl_gc_mark_cache_t *gc_cache, jl_gc_mark_sp_t *sp) // constants gc_mark_queue_obj(gc_cache, sp, jl_emptytuple_type); + if (cmpswap_names != NULL) + gc_mark_queue_obj(gc_cache, sp, cmpswap_names); } // find unmarked objects that need to be finalized from the finalizer list "list". diff --git a/src/init.c b/src/init.c index 77833033d95bd0..1c58753506fb7a 100644 --- a/src/init.c +++ b/src/init.c @@ -841,6 +841,7 @@ static void post_boot_hooks(void) jl_methoderror_type = (jl_datatype_t*)core("MethodError"); jl_loaderror_type = (jl_datatype_t*)core("LoadError"); jl_initerror_type = (jl_datatype_t*)core("InitError"); + jl_pair_type = core("Pair"); jl_weakref_type = (jl_datatype_t*)core("WeakRef"); jl_vecelement_typename = ((jl_datatype_t*)jl_unwrap_unionall(core("VecElement")))->name; diff --git a/src/jl_exported_data.inc b/src/jl_exported_data.inc index 3cebe459bf6432..b8d5ae0e35b29f 100644 --- a/src/jl_exported_data.inc +++ b/src/jl_exported_data.inc @@ -74,6 +74,7 @@ XX(jl_number_type) \ XX(jl_opaque_closure_type) \ XX(jl_opaque_closure_typename) \ + XX(jl_pair_type) \ XX(jl_partial_opaque_type) \ XX(jl_partial_struct_type) \ XX(jl_phicnode_type) \ diff --git a/src/jl_exported_funcs.inc b/src/jl_exported_funcs.inc index c85b1a48e2ba49..256fdfeaa0890d 100644 --- a/src/jl_exported_funcs.inc +++ b/src/jl_exported_funcs.inc @@ -11,6 +11,7 @@ XX(jl_alloc_svec_uninit) \ XX(jl_alloc_vec_any) \ XX(jl_apply_array_type) \ + XX(jl_apply_cmpswap_type) \ XX(jl_apply_generic) \ XX(jl_apply_tuple_type) \ XX(jl_apply_tuple_type_v) \ @@ -549,3 +550,4 @@ XX(jl_vprintf) \ XX(jl_wakeup_thread) \ XX(jl_yield) \ + diff --git a/src/jltypes.c b/src/jltypes.c index 1ae49c0a32eabc..aacd2ba19ccca4 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -19,6 +19,8 @@ extern "C" { #endif +jl_value_t *cmpswap_names JL_GLOBALLY_ROOTED; + // compute empirical max-probe for a given size #define max_probe(size) ((size) <= 1024 ? 16 : (size) >> 6) #define h2index(hv, sz) (size_t)((hv) & ((sz)-1)) @@ -977,20 +979,42 @@ jl_value_t *jl_apply_type(jl_value_t *tc, jl_value_t **params, size_t n) JL_DLLEXPORT jl_value_t *jl_apply_type1(jl_value_t *tc, jl_value_t *p1) { - JL_GC_PUSH1(&p1); - jl_value_t *t = jl_apply_type(tc, &p1, 1); - JL_GC_POP(); - return t; + return jl_apply_type(tc, &p1, 1); } JL_DLLEXPORT jl_value_t *jl_apply_type2(jl_value_t *tc, jl_value_t *p1, jl_value_t *p2) { - jl_value_t **args; - JL_GC_PUSHARGS(args, 2); - args[0] = p1; args[1] = p2; - jl_value_t *t = jl_apply_type(tc, args, 2); - JL_GC_POP(); - return t; + jl_value_t *args[2]; + args[0] = p1; + args[1] = p2; + return jl_apply_type(tc, args, 2); +} + +jl_datatype_t *jl_apply_modify_type(jl_value_t *dt) +{ + jl_datatype_t *rettyp = (jl_datatype_t*)jl_apply_type2(jl_pair_type, dt, dt); + JL_GC_PROMISE_ROOTED(rettyp); // (JL_ALWAYS_LEAFTYPE) + return rettyp; +} + +jl_datatype_t *jl_apply_cmpswap_type(jl_value_t *dt) +{ + jl_value_t *params[2]; + jl_value_t *names = jl_atomic_load_relaxed(&cmpswap_names); + if (names == NULL) { + params[0] = jl_symbol("old"); + params[1] = jl_symbol("success"); + jl_value_t *lnames = jl_f_tuple(NULL, params, 2); + if (jl_atomic_cmpswap(&cmpswap_names, &names, lnames)) + names = jl_atomic_load_relaxed(&cmpswap_names); // == lnames + } + params[0] = dt; + params[1] = (jl_value_t*)jl_bool_type; + jl_datatype_t *tuptyp = jl_apply_tuple_type_v(params, 2); + JL_GC_PROMISE_ROOTED(tuptyp); // (JL_ALWAYS_LEAFTYPE) + jl_datatype_t *rettyp = (jl_datatype_t*)jl_apply_type2(jl_namedtuple_type, names, tuptyp); + JL_GC_PROMISE_ROOTED(rettyp); // (JL_ALWAYS_LEAFTYPE) + return rettyp; } JL_DLLEXPORT jl_value_t *jl_tupletype_fill(size_t n, jl_value_t *v) diff --git a/src/julia.h b/src/julia.h index 9afd7301fc5bc4..e6edc71b42dfa1 100644 --- a/src/julia.h +++ b/src/julia.h @@ -707,6 +707,7 @@ extern JL_DLLIMPORT jl_typename_t *jl_llvmpointer_typename JL_GLOBALLY_ROOTED; extern JL_DLLIMPORT jl_typename_t *jl_namedtuple_typename JL_GLOBALLY_ROOTED; extern JL_DLLIMPORT jl_unionall_t *jl_namedtuple_type JL_GLOBALLY_ROOTED; extern JL_DLLIMPORT jl_datatype_t *jl_task_type JL_GLOBALLY_ROOTED; +extern JL_DLLIMPORT jl_value_t *jl_pair_type JL_GLOBALLY_ROOTED; extern JL_DLLIMPORT jl_value_t *jl_array_uint8_type JL_GLOBALLY_ROOTED; extern JL_DLLIMPORT jl_value_t *jl_array_any_type JL_GLOBALLY_ROOTED; @@ -1362,6 +1363,8 @@ JL_DLLEXPORT jl_value_t *jl_instantiate_unionall(jl_unionall_t *u, jl_value_t *p JL_DLLEXPORT jl_value_t *jl_apply_type(jl_value_t *tc, jl_value_t **params, size_t n); JL_DLLEXPORT jl_value_t *jl_apply_type1(jl_value_t *tc, jl_value_t *p1); JL_DLLEXPORT jl_value_t *jl_apply_type2(jl_value_t *tc, jl_value_t *p1, jl_value_t *p2); +JL_DLLEXPORT jl_datatype_t *jl_apply_modify_type(jl_value_t *dt); +JL_DLLEXPORT jl_datatype_t *jl_apply_cmpswap_type(jl_value_t *dt); JL_DLLEXPORT jl_tupletype_t *jl_apply_tuple_type(jl_svec_t *params); JL_DLLEXPORT jl_tupletype_t *jl_apply_tuple_type_v(jl_value_t **p, size_t np); JL_DLLEXPORT jl_datatype_t *jl_new_datatype(jl_sym_t *name, @@ -1384,7 +1387,7 @@ JL_DLLEXPORT jl_value_t *jl_atomic_new_bits(jl_value_t *dt, const char *src); JL_DLLEXPORT void jl_atomic_store_bits(char *dst, const jl_value_t *src, int nb); JL_DLLEXPORT jl_value_t *jl_atomic_swap_bits(jl_value_t *dt, char *dst, const jl_value_t *src, int nb); JL_DLLEXPORT int jl_atomic_bool_cmpswap_bits(char *dst, const jl_value_t *expected, const jl_value_t *src, int nb); -JL_DLLEXPORT jl_value_t *jl_atomic_cmpswap_bits(jl_datatype_t *dt, char *dst, const jl_value_t *expected, const jl_value_t *src, int nb); +JL_DLLEXPORT jl_value_t *jl_atomic_cmpswap_bits(jl_datatype_t *dt, jl_datatype_t *rettype, char *dst, const jl_value_t *expected, const jl_value_t *src, int nb); JL_DLLEXPORT jl_value_t *jl_new_struct(jl_datatype_t *type, ...); JL_DLLEXPORT jl_value_t *jl_new_structv(jl_datatype_t *type, jl_value_t **args, uint32_t na); JL_DLLEXPORT jl_value_t *jl_new_structt(jl_datatype_t *type, jl_value_t *tup); diff --git a/src/runtime_intrinsics.c b/src/runtime_intrinsics.c index 7cb58bc2302942..be78be74172cbc 100644 --- a/src/runtime_intrinsics.c +++ b/src/runtime_intrinsics.c @@ -175,12 +175,16 @@ JL_DLLEXPORT jl_value_t *jl_atomic_pointermodify(jl_value_t *p, jl_value_t *f, j args[0] = expected; jl_gc_safepoint(); } - // args[0] == expected (old); args[1] == y (new) - args[0] = jl_f_tuple(NULL, args, 2); + // args[0] == expected (old) + // args[1] == y (new) + jl_datatype_t *rettyp = jl_apply_modify_type(ety); + JL_GC_PROMISE_ROOTED(rettyp); // (JL_ALWAYS_LEAFTYPE) + args[0] = jl_new_struct(rettyp, args[0], args[1]); JL_GC_POP(); return args[0]; } + 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(atomic_pointerreplace, pointer, p); @@ -193,20 +197,21 @@ JL_DLLEXPORT jl_value_t *jl_atomic_pointerreplace(jl_value_t *p, jl_value_t *exp // TODO: filter other invalid orderings jl_value_t *ety = jl_tparam0(jl_typeof(p)); char *pp = (char*)jl_unbox_long(p); + jl_datatype_t *rettyp = jl_apply_cmpswap_type(ety); + JL_GC_PROMISE_ROOTED(rettyp); // (JL_ALWAYS_LEAFTYPE) if (ety == (jl_value_t*)jl_any_type) { - jl_value_t **result; - JL_GC_PUSHARGS(result, 2); - result[0] = expected; + jl_value_t *result; + JL_GC_PUSH1(&result); + result = expected; int success; while (1) { - success = jl_atomic_cmpswap((jl_value_t**)pp, &result[0], x); - if (success || !jl_egal(result[0], expected)) + success = jl_atomic_cmpswap((jl_value_t**)pp, &result, x); + if (success || !jl_egal(result, expected)) break; } - result[1] = success ? jl_true : jl_false; - result[0] = jl_f_tuple(NULL, result, 2); + result = jl_new_struct(rettyp, result, success ? jl_true : jl_false); JL_GC_POP(); - return result[0]; + return result; } else { if (!is_valid_intrinsic_elptr(ety)) @@ -216,7 +221,7 @@ JL_DLLEXPORT jl_value_t *jl_atomic_pointerreplace(jl_value_t *p, jl_value_t *exp size_t nb = jl_datatype_size(ety); if ((nb & (nb - 1)) != 0 || nb > MAX_POINTERATOMIC_SIZE) jl_error("atomic_pointerreplace: invalid pointer for atomic operation"); - return jl_atomic_cmpswap_bits((jl_datatype_t*)ety, pp, expected, x, nb); + return jl_atomic_cmpswap_bits((jl_datatype_t*)ety, rettyp, pp, expected, x, nb); } } diff --git a/src/staticdata.c b/src/staticdata.c index 8fa1613b075a81..f5892d4218e714 100644 --- a/src/staticdata.c +++ b/src/staticdata.c @@ -30,7 +30,7 @@ extern "C" { // TODO: put WeakRefs on the weak_refs list during deserialization // TODO: handle finalizers -#define NUM_TAGS 150 +#define NUM_TAGS 151 // An array of references that need to be restored from the sysimg // This is a manually constructed dual of the gvars array, which would be produced by codegen for Julia code, for C. @@ -127,6 +127,7 @@ jl_value_t **const*const get_tags(void) { INSERT_TAG(jl_floatingpoint_type); INSERT_TAG(jl_number_type); INSERT_TAG(jl_signed_type); + INSERT_TAG(jl_pair_type); // special typenames INSERT_TAG(jl_tuple_typename); diff --git a/test/atomics.jl b/test/atomics.jl index 4c32fc12d87edb..c53471ed0da26b 100644 --- a/test/atomics.jl +++ b/test/atomics.jl @@ -4,6 +4,8 @@ using Test, Base.Threads using Core: ConcurrencyViolationError import Base: copy +const ReplaceType = ccall(:jl_apply_cmpswap_type, Any, (Any,), T) where T + mutable struct ARefxy{T} @atomic x::T y::T @@ -86,17 +88,18 @@ Base.show(io::IO, x::Int24) = print(io, "Int24(", Core.Intrinsics.zext_int(Int, @noinline function _test_field_operators(r) r = r[] + TT = fieldtype(typeof(r), :x) T = typeof(getfield(r, :x)) @test getfield(r, :x, :sequentially_consistent) === T(123_10) @test setfield!(r, :x, T(123_1), :sequentially_consistent) === T(123_1) @test getfield(r, :x, :sequentially_consistent) === T(123_1) - @test replacefield!(r, :x, 123_1 % UInt, T(123_30), :sequentially_consistent, :sequentially_consistent) === (T(123_1), false) - @test replacefield!(r, :x, T(123_1), T(123_30), :sequentially_consistent, :sequentially_consistent) === (T(123_1), true) + @test replacefield!(r, :x, 123_1 % UInt, T(123_30), :sequentially_consistent, :sequentially_consistent) === ReplaceType{TT}((T(123_1), false)) + @test replacefield!(r, :x, T(123_1), T(123_30), :sequentially_consistent, :sequentially_consistent) === ReplaceType{TT}((T(123_1), true)) @test getfield(r, :x, :sequentially_consistent) === T(123_30) - @test replacefield!(r, :x, T(123_1), T(123_1), :sequentially_consistent, :sequentially_consistent) === (T(123_30), false) + @test replacefield!(r, :x, T(123_1), T(123_1), :sequentially_consistent, :sequentially_consistent) === ReplaceType{TT}((T(123_30), false)) @test getfield(r, :x, :sequentially_consistent) === T(123_30) - @test modifyfield!(r, :x, add, 1, :sequentially_consistent) === (T(123_30), T(123_31)) - @test modifyfield!(r, :x, add, 1, :sequentially_consistent) === (T(123_31), T(123_32)) + @test modifyfield!(r, :x, add, 1, :sequentially_consistent) === Pair{TT,TT}(T(123_30), T(123_31)) + @test modifyfield!(r, :x, add, 1, :sequentially_consistent) === Pair{TT,TT}(T(123_31), T(123_32)) @test getfield(r, :x, :sequentially_consistent) === T(123_32) @test swapfield!(r, :x, T(123_1), :sequentially_consistent) === T(123_32) @test getfield(r, :x, :sequentially_consistent) === T(123_1) @@ -120,6 +123,7 @@ test_field_operators(ARefxy{Float64}(123_10, 123_20)) @noinline function _test_field_orderings(r, x, y) @nospecialize x y r = r[] + TT = fieldtype(typeof(r), :x) @test getfield(r, :x) === x @test_throws ConcurrencyViolationError("invalid atomic ordering") getfield(r, :x, :u) @@ -199,7 +203,7 @@ test_field_operators(ARefxy{Float64}(123_10, 123_20)) @test_throws ConcurrencyViolationError("modifyfield!: non-atomic field cannot be written atomically") modifyfield!(r, :y, swap, y, :release) @test_throws ConcurrencyViolationError("modifyfield!: non-atomic field cannot be written atomically") modifyfield!(r, :y, swap, y, :acquire_release) @test_throws ConcurrencyViolationError("modifyfield!: non-atomic field cannot be written atomically") modifyfield!(r, :y, swap, y, :sequentially_consistent) - @test modifyfield!(r, :y, swap, x, :not_atomic) === (y, x) + @test modifyfield!(r, :y, swap, x, :not_atomic) === Pair{TT,TT}(y, x) @test_throws ConcurrencyViolationError("invalid atomic ordering") replacefield!(r, :y, y, y, :u, :not_atomic) @test_throws ConcurrencyViolationError("invalid atomic ordering") replacefield!(r, :y, y, y, :unordered, :not_atomic) @@ -215,10 +219,10 @@ test_field_operators(ARefxy{Float64}(123_10, 123_20)) @test_throws ConcurrencyViolationError("invalid atomic ordering") replacefield!(r, :y, y, y, :not_atomic, :release) @test_throws ConcurrencyViolationError("invalid atomic ordering") replacefield!(r, :y, y, y, :not_atomic, :acquire_release) @test_throws ConcurrencyViolationError("invalid atomic ordering") replacefield!(r, :y, y, y, :not_atomic, :sequentially_consistent) - @test replacefield!(r, :y, x, y, :not_atomic, :not_atomic) === (x, true) - @test replacefield!(r, :y, x, y, :not_atomic, :not_atomic) === (y, x === y) - @test replacefield!(r, :y, y, y, :not_atomic) === (y, true) - @test replacefield!(r, :y, y, y) === (y, true) + @test replacefield!(r, :y, x, y, :not_atomic, :not_atomic) === ReplaceType{TT}((x, true)) + @test replacefield!(r, :y, x, y, :not_atomic, :not_atomic) === ReplaceType{TT}((y, x === y)) + @test replacefield!(r, :y, y, y, :not_atomic) === ReplaceType{TT}((y, true)) + @test replacefield!(r, :y, y, y) === ReplaceType{TT}((y, true)) @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) @@ -234,11 +238,11 @@ test_field_operators(ARefxy{Float64}(123_10, 123_20)) @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_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) - @test modifyfield!(r, :x, swap, x, :acquire_release) === (x, x) - @test modifyfield!(r, :x, swap, x, :sequentially_consistent) === (x, x) + @test modifyfield!(r, :x, swap, x, :monotonic) === Pair{TT,TT}(x, x) + @test modifyfield!(r, :x, swap, x, :acquire) === Pair{TT,TT}(x, x) + @test modifyfield!(r, :x, swap, x, :release) === Pair{TT,TT}(x, x) + @test modifyfield!(r, :x, swap, x, :acquire_release) === Pair{TT,TT}(x, x) + @test modifyfield!(r, :x, swap, x, :sequentially_consistent) === Pair{TT,TT}(x, x) @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) @@ -256,9 +260,9 @@ test_field_operators(ARefxy{Float64}(123_10, 123_20)) @test_throws ConcurrencyViolationError("invalid atomic ordering") replacefield!(r, :x, x, x, :not_atomic, :release) @test_throws ConcurrencyViolationError("invalid atomic ordering") replacefield!(r, :x, x, x, :not_atomic, :acquire_release) @test_throws ConcurrencyViolationError("invalid atomic ordering") replacefield!(r, :x, x, x, :not_atomic, :sequentially_consistent) - @test replacefield!(r, :x, x, y, :sequentially_consistent, :sequentially_consistent) === (x, true) - @test replacefield!(r, :x, x, y, :sequentially_consistent, :sequentially_consistent) === (y, x === y) - @test replacefield!(r, :x, y, x, :sequentially_consistent) === (y, true) + @test replacefield!(r, :x, x, y, :sequentially_consistent, :sequentially_consistent) === ReplaceType{TT}((x, true)) + @test replacefield!(r, :x, x, y, :sequentially_consistent, :sequentially_consistent) === ReplaceType{TT}((y, x === y)) + @test replacefield!(r, :x, y, x, :sequentially_consistent) === ReplaceType{TT}((y, true)) nothing end @noinline function test_field_orderings(r, x, y) @@ -339,10 +343,10 @@ let a = ARefxy(1, -1) @test 12 === @atomic :monotonic a.x *= 3 @test 12 === @atomic a.x - @test (12, 13) === @atomic a.x + 1 - @test (13, 15) === @atomic :monotonic a.x + 2 - @test (15, 19) === @atomic a.x max 19 - @test (19, 20) === @atomic :monotonic a.x max 20 + @test (12 => 13) === @atomic a.x + 1 + @test (13 => 15) === @atomic :monotonic a.x + 2 + @test (15 => 19) === @atomic a.x max 19 + @test (19 => 20) === @atomic :monotonic a.x max 20 @test_throws ConcurrencyViolationError @atomic :not_atomic a.x + 1 @test_throws ConcurrencyViolationError @atomic :not_atomic a.x max 30 @@ -352,17 +356,17 @@ let a = ARefxy(1, -1) @test_throws ConcurrencyViolationError @atomicswap :not_atomic a.x = 1 @test 2 === @atomic a.x - @test (2, true) === @atomicreplace a.x 2 => 1 - @test (1, false) === @atomicreplace :monotonic a.x 2 => 1 - @test (1, false) === @atomicreplace :monotonic :monotonic a.x 2 => 1 + @test ReplaceType{Int}((2, true)) === @atomicreplace a.x 2 => 1 + @test ReplaceType{Int}((1, false)) === @atomicreplace :monotonic a.x 2 => 1 + @test ReplaceType{Int}((1, false)) === @atomicreplace :monotonic :monotonic a.x 2 => 1 @test_throws ConcurrencyViolationError @atomicreplace :not_atomic a.x 1 => 2 @test_throws ConcurrencyViolationError @atomicreplace :monotonic :acquire a.x 1 => 2 @test 1 === @atomic a.x xchg = 1 => 2 - @test (1, true) === @atomicreplace a.x xchg - @test (2, false) === @atomicreplace :monotonic a.x xchg - @test (2, false) === @atomicreplace :acquire_release :monotonic a.x xchg + @test ReplaceType{Int}((1, true)) === @atomicreplace a.x xchg + @test ReplaceType{Int}((2, false)) === @atomicreplace :monotonic a.x xchg + @test ReplaceType{Int}((2, false)) === @atomicreplace :acquire_release :monotonic a.x xchg @test_throws ConcurrencyViolationError @atomicreplace :not_atomic a.x xchg @test_throws ConcurrencyViolationError @atomicreplace :monotonic :acquire a.x xchg end diff --git a/test/intrinsics.jl b/test/intrinsics.jl index 7fa8ecb0ebe278..7fb6bd651ebc09 100644 --- a/test/intrinsics.jl +++ b/test/intrinsics.jl @@ -100,6 +100,8 @@ let f = Core.Intrinsics.ashr_int @test f(Int32(2), -1) == 0 end +const ReplaceType = ccall(:jl_apply_cmpswap_type, Any, (Any,), T) where T + # issue #29929 let p = Ptr{Nothing}(0) @test unsafe_store!(p, nothing) === C_NULL @@ -107,9 +109,9 @@ let p = Ptr{Nothing}(0) @test Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) === nothing @test Core.Intrinsics.atomic_pointerset(p, nothing, :sequentially_consistent) === p @test Core.Intrinsics.atomic_pointerswap(p, nothing, :sequentially_consistent) === nothing - @test Core.Intrinsics.atomic_pointermodify(p, (i, j) -> j, nothing, :sequentially_consistent) === (nothing, nothing) - @test Core.Intrinsics.atomic_pointerreplace(p, nothing, nothing, :sequentially_consistent, :sequentially_consistent) === (nothing, true) - @test Core.Intrinsics.atomic_pointerreplace(p, missing, nothing, :sequentially_consistent, :sequentially_consistent) === (nothing, false) + @test Core.Intrinsics.atomic_pointermodify(p, (i, j) -> j, nothing, :sequentially_consistent) === Pair(nothing, nothing) + @test Core.Intrinsics.atomic_pointerreplace(p, nothing, nothing, :sequentially_consistent, :sequentially_consistent) === ReplaceType{Nothing}((nothing, true)) + @test Core.Intrinsics.atomic_pointerreplace(p, missing, nothing, :sequentially_consistent, :sequentially_consistent) === ReplaceType{Nothing}((nothing, false)) end struct GhostStruct end @@ -199,24 +201,24 @@ for TT in (Int8, Int16, Int32, Int64, Int128, Int256, Int512, Complex{Int32}, Co @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_pointerreplace(p, T(1), T(100), :sequentially_consistent, :sequentially_consistent) === ReplaceType{TT}((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_pointerreplace(p, T(1), T(1), :sequentially_consistent, :sequentially_consistent) === ReplaceType{TT}((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_pointermodify(p, add, T(1), :sequentially_consistent) === Pair{TT,TT}(T(100), T(101)) + @test Core.Intrinsics.atomic_pointermodify(p, add, T(1), :sequentially_consistent) === Pair{TT,TT}(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_pointerreplace(p, S(100), T(2), :sequentially_consistent, :sequentially_consistent) === ReplaceType{TT}((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_pointermodify(p, swap, S(103), :sequentially_consistent) === Pair{TT,TT}(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_pointerreplace(p, T(100), S(2), :sequentially_consistent, :sequentially_consistent) === ReplaceType{TT}((S(100), false)) + @test Core.Intrinsics.atomic_pointerreplace(p, S(100), T(2), :sequentially_consistent, :sequentially_consistent) === ReplaceType{TT}((S(100), true)) @test Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) === T(2) end end)(TT,) diff --git a/test/show.jl b/test/show.jl index c00dcf523898ca..1552214d2516eb 100644 --- a/test/show.jl +++ b/test/show.jl @@ -1769,7 +1769,7 @@ end # spurious binding resolutions show(IOContext(b, :module => TestShowType), Base.Pair) @test !Base.isbindingresolved(TestShowType, :Pair) - @test String(take!(b)) == "Base.Pair" + @test String(take!(b)) == "Core.Pair" show(IOContext(b, :module => TestShowType), Base.Complex) @test Base.isbindingresolved(TestShowType, :Complex) @test String(take!(b)) == "Complex" From c12e63fba350d4fa635a9b82acbd0118ac428f36 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Tue, 10 Aug 2021 22:09:39 -0400 Subject: [PATCH 044/135] Profile: allocate buffer for n instruction pointers per thread (#41821) --- stdlib/Profile/src/Profile.jl | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/stdlib/Profile/src/Profile.jl b/stdlib/Profile/src/Profile.jl index f297ad12f80a16..fbb9a820e76913 100644 --- a/stdlib/Profile/src/Profile.jl +++ b/stdlib/Profile/src/Profile.jl @@ -40,10 +40,14 @@ end init(; n::Integer, delay::Real)) Configure the `delay` between backtraces (measured in seconds), and the number `n` of -instruction pointers that may be stored. Each instruction pointer corresponds to a single +instruction pointers that may be stored per thread. Each instruction pointer corresponds to a single line of code; backtraces generally consist of a long list of instruction pointers. Current settings can be obtained by calling this function with no arguments, and each can be set independently using keywords or in the order `(n, delay)`. + +!!! compat "Julia 1.8" + As of Julia 1.8, this function allocates space for `n` instruction pointers per thread being profiled. + Previously this was `n` total. """ function init(; n::Union{Nothing,Integer} = nothing, delay::Union{Nothing,Real} = nothing) n_cur = ccall(:jl_profile_maxlen_data, Csize_t, ()) @@ -51,15 +55,17 @@ function init(; n::Union{Nothing,Integer} = nothing, delay::Union{Nothing,Real} if n === nothing && delay === nothing return Int(n_cur), delay_cur end - nnew = (n === nothing) ? n_cur : n + nthreads = Sys.iswindows() ? 1 : Threads.nthreads() # windows only profiles the main thread + nnew = (n === nothing) ? n_cur : n * nthreads delaynew = (delay === nothing) ? delay_cur : delay init(nnew, delaynew) end function init(n::Integer, delay::Real) - status = ccall(:jl_profile_init, Cint, (Csize_t, UInt64), n, round(UInt64,10^9*delay)) + nthreads = Sys.iswindows() ? 1 : Threads.nthreads() # windows only profiles the main thread + status = ccall(:jl_profile_init, Cint, (Csize_t, UInt64), n * nthreads, round(UInt64,10^9*delay)) if status == -1 - error("could not allocate space for ", n, " instruction pointers") + error("could not allocate space for ", n, " instruction pointers per thread being profiled ($nthreads threads)") end end From 59fe04fde55d6af2e0f4aa7eb7a11d6dbe655d56 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Wed, 11 Aug 2021 08:22:54 -0400 Subject: [PATCH 045/135] make clean external stdlib clones (#41861) --- stdlib/Makefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/stdlib/Makefile b/stdlib/Makefile index 38c8c45ac89756..e782d92eab2b96 100644 --- a/stdlib/Makefile +++ b/stdlib/Makefile @@ -73,7 +73,11 @@ getall get: $(addprefix get-, $(STDLIBS_EXT) $(JLL_NAMES)) install: version-check $(addprefix install-, $(STDLIBS_EXT) $(JLL_NAMES)) $(STDLIBS_LINK_TARGETS) version-check: $(addprefix version-check-, $(STDLIBS_EXT)) uninstall: $(addprefix uninstall-, $(STDLIBS_EXT)) -clean: $(addprefix clean-, $(STDLIBS_EXT)) $(CLEAN_TARGETS) +extstdlibclean: + for module in $(STDLIBS_EXT) ; do \ + rm -rf $(JULIAHOME)/stdlib/$${module}-*; \ + done +clean: $(addprefix clean-, $(STDLIBS_EXT)) $(CLEAN_TARGETS) extstdlibclean distclean: $(addprefix distclean-, $(STDLIBS_EXT)) clean checksumall: $(addprefix checksum-, $(STDLIBS_EXT)) From 6469ca538482d0751c69a3723ad97d2728da2f5e Mon Sep 17 00:00:00 2001 From: SamuraiAku <61489439+SamuraiAku@users.noreply.github.com> Date: Wed, 11 Aug 2021 07:37:24 -0700 Subject: [PATCH 046/135] THIRDPARTY.md cleanup (#41674) * Add LLVM project license text to src/disasm.cpp * Remove mention of third party code from header in src/jitlayers.cpp, since there are no markings of third party code in the actual source code. Update THIRDPARTY.md as well * More precise reference to source files using MUSL code in THIRDPARTY.md * Remove reference to joinpath in Python section of THIRDPARTY.md. The function does not appear to exist * Removed reference to cyclecount from THIRDPARTY.md since it does not apear to exist in the codebase * Remove reference to grisu from THIRDPARTY.md. This code was deleted a while ago * base/special/exp.jl was previously rewritten so that it no longer uses third party code. Remove reference from THIRDPARTY.md and add standard Julia header to exp.jl. See comments in #41095 * Add BSD-3 license to src/flisp * In THIRDPARTY.md, move FEMTOLISP reference to the third party code in src section. This is the proper location for the reference since the code is part of the Julia repository and not an external dependency * In THIRDPARTY.md, change the LIBUNWIND license link to the repository Julia actually pulls the dependency from * In THIRDPARTY.md, change the LIBUV license link to the repository Julia actually pulls the dependency from * Clearly mark references to LLVM open source license as UIUC not BSD-3. They are very similar but are recognized as different licenses. * In THIRDPARTY.md, change the DSFMT license link to the respository Julia actually pulls the code from. * In THIRDPARTY.md, change the MBEDTLS license link to the repository Julia actually pulls from. The license in that repo is Apache 2.0 only, which is the default for the project anyhow, so I removed mention of the alternate GPL licensing option * In THIRDPARTY.md, change the SUITESPARSE license link to the repository Julia pulls the dependency from. * Add missing reference to LIBBLASTRAMPOLINE in THIRDPARTY.md * Add missing reference to LIBWHICH in THIRDPARTY.md * Add missing reference to NGHTTP2 in THIRDPARTY.md * Add hyperlinks between LICENSE.md and THIRDPARTY.md * In THIRDPARTY.md, move LIBWHICH from stdlib dependencies to build tools --- LICENSE.md | 2 +- THIRDPARTY.md | 29 +++++++++++++++-------------- base/special/exp.jl | 2 ++ src/disasm.cpp | 40 +++++++++++++++++++++++++++++++++++++--- src/flisp/LICENSE | 26 ++++++++++++++++++++++++++ src/jitlayers.cpp | 2 -- 6 files changed, 81 insertions(+), 20 deletions(-) create mode 100644 src/flisp/LICENSE diff --git a/LICENSE.md b/LICENSE.md index 79127224d049b9..1083622cdc2eb4 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -23,4 +23,4 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. end of terms and conditions -Please see THIRDPARTY.md for license information for other software used in this project. +Please see [THIRDPARTY.md](./THIRDPARTY.md) for license information for other software used in this project. diff --git a/THIRDPARTY.md b/THIRDPARTY.md index 87304437183d68..32ef8eacd9ce48 100644 --- a/THIRDPARTY.md +++ b/THIRDPARTY.md @@ -1,51 +1,52 @@ -The Julia language is licensed under the MIT License (see `LICENSE.md`). The "language" consists +The Julia language is licensed under the MIT License (see [LICENSE.md](./LICENSE.md) ). The "language" consists of the compiler (the contents of src/), most of the standard library (base/), and some utilities (most of the rest of the files in this repository). See below for exceptions. - [crc32c.c](https://stackoverflow.com/questions/17645167/implementing-sse-4-2s-crc32c-in-software) (CRC-32c checksum code by Mark Adler) [[ZLib](https://opensource.org/licenses/Zlib)]. - [LDC](https://github.com/ldc-developers/ldc/blob/master/LICENSE) (for ccall/cfunction ABI definitions) [BSD-3]. The portion of code that Julia uses from LDC is [BSD-3] licensed. -- [LLVM](https://releases.llvm.org/3.9.0/LICENSE.TXT) (for parts of src/jitlayers.cpp and src/disasm.cpp) [BSD-3, effectively] -- [MUSL](https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT) (for getopt implementation on Windows) [MIT] +- [LLVM](https://releases.llvm.org/3.9.0/LICENSE.TXT) (for parts of src/disasm.cpp) [UIUC] +- [MUSL](https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT) (for src/getopt.c and src/getopt.h) [MIT] - [MINGW](https://sourceforge.net/p/mingw/mingw-org-wsl/ci/legacy/tree/mingwrt/mingwex/dirname.c) (for dirname implementation on Windows) [MIT] - [NetBSD](https://www.netbsd.org/about/redistribution.html) (for setjmp, longjmp, and strptime implementations on Windows) [BSD-3] -- [Python](https://docs.python.org/3/license.html) (for strtod and joinpath implementation on Windows) [BSD-3, effectively] -- [Google Benchmark](https://github.com/google/benchmark) (for cyclecount implementation) [Apache 2.0] +- [Python](https://docs.python.org/3/license.html) (for strtod implementation on Windows) [PSF] +- [FEMTOLISP](https://github.com/JeffBezanson/femtolisp) [BSD-3] The following components included in Julia `Base` have their own separate licenses: - base/ryu/* [Boost] (see [ryu](https://github.com/ulfjack/ryu/blob/master/LICENSE-Boost)) -- base/grisu/* [BSD-3] (see [double-conversion](https://github.com/google/double-conversion/blob/master/LICENSE)) -- base/special/{exp,rem_pio2,hyperbolic}.jl [Freely distributable with preserved copyright notice] (see [FDLIBM](https://www.netlib.org/fdlibm)) +- base/special/{rem_pio2,hyperbolic}.jl [Freely distributable with preserved copyright notice] (see [FDLIBM](https://www.netlib.org/fdlibm)) The Julia language links to the following external libraries, which have their own licenses: -- [FEMTOLISP](https://github.com/JeffBezanson/femtolisp) [BSD-3] -- [LIBUNWIND](https://git.savannah.gnu.org/gitweb/?p=libunwind.git;a=blob_plain;f=LICENSE;hb=master) [MIT] -- [LIBUV](https://github.com/joyent/libuv/blob/master/LICENSE) [MIT] -- [LLVM](https://releases.llvm.org/6.0.0/LICENSE.TXT) [BSD-3, effectively] +- [LIBUNWIND](https://github.com/libunwind/libunwind/blob/master/LICENSE) [MIT] +- [LIBUV](https://github.com/JuliaLang/libuv/blob/julia-uv2-1.39.0/LICENSE) [MIT] +- [LLVM](https://releases.llvm.org/6.0.0/LICENSE.TXT) [UIUC] - [UTF8PROC](https://github.com/JuliaStrings/utf8proc) [MIT] Julia's `stdlib` uses the following external libraries, which have their own licenses: -- [DSFMT](http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/LICENSE.txt) [BSD-3] +- [DSFMT](https://github.com/MersenneTwister-Lab/dSFMT/blob/master/LICENSE.txt) [BSD-3] - [OPENLIBM](https://github.com/JuliaMath/openlibm/blob/master/LICENSE.md) [MIT, BSD-2, ISC] - [GMP](https://gmplib.org/manual/Copying.html#Copying) [LGPL3+ or GPL2+] - [LIBGIT2](https://github.com/libgit2/libgit2/blob/development/COPYING) [GPL2+ with unlimited linking exception] - [CURL](https://curl.haxx.se/docs/copyright.html) [MIT/X derivative] - [LIBSSH2](https://github.com/libssh2/libssh2/blob/master/COPYING) [BSD-3] -- [MBEDTLS](https://tls.mbed.org/how-to-get) [either GPLv2 or Apache 2.0] +- [MBEDTLS](https://github.com/ARMmbed/mbedtls/blob/development/LICENSE) [Apache 2.0] - [MPFR](https://www.mpfr.org/mpfr-current/mpfr.html#Copying) [LGPL3+] - [OPENBLAS](https://raw.github.com/xianyi/OpenBLAS/master/LICENSE) [BSD-3] - [LAPACK](https://netlib.org/lapack/LICENSE.txt) [BSD-3] - [PCRE](https://www.pcre.org/licence.txt) [BSD-3] -- [SUITESPARSE](http://suitesparse.com) [mix of LGPL2+ and GPL2+; see individual module licenses] +- [SUITESPARSE](https://github.com/DrTimothyAldenDavis/SuiteSparse/blob/master/LICENSE.txt) [mix of LGPL2+ and GPL2+; see individual module licenses] +- [LIBBLASTRAMPOLINE](https://github.com/staticfloat/libblastrampoline/blob/main/LICENSE) [MIT] +- [NGHTTP2](https://github.com/nghttp2/nghttp2/blob/master/COPYING) [MIT] Julia's build process uses the following external tools: - [PATCHELF](https://nixos.org/patchelf.html) - [OBJCONV](https://www.agner.org/optimize/#objconv) +- [LIBWHICH](https://github.com/vtjnash/libwhich/blob/master/LICENSE) [MIT] Julia bundles the following external programs and libraries: diff --git a/base/special/exp.jl b/base/special/exp.jl index fd88eee3fc6385..110cd93410d73a 100644 --- a/base/special/exp.jl +++ b/base/special/exp.jl @@ -1,3 +1,5 @@ +# This file is a part of Julia. License is MIT: https://julialang.org/license + # magic rounding constant: 1.5*2^52 Adding, then subtracting it from a float rounds it to an Int. # This works because eps(MAGIC_ROUND_CONST(T)) == one(T), so adding it to a smaller number aligns the lsb to the 1s place. # Values for which this trick doesn't work are going to have outputs of 0 or Inf. diff --git a/src/disasm.cpp b/src/disasm.cpp index afcd8d65659e92..6157873ad71c5f 100644 --- a/src/disasm.cpp +++ b/src/disasm.cpp @@ -5,11 +5,45 @@ // // Original copyright: // -// The LLVM Compiler Infrastructure +// University of Illinois/NCSA +// Open Source License +// Copyright (c) 2003-2016 University of Illinois at Urbana-Champaign. +// All rights reserved. // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Developed by: // +// LLVM Team +// +// University of Illinois at Urbana-Champaign +// +// http://llvm.org +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal with +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +// of the Software, and to permit persons to whom the Software is furnished to do +// so, subject to the following conditions: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimers. +// +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimers in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the names of the LLVM Team, University of Illinois at +// Urbana-Champaign, nor the names of its contributors may be used to +// endorse or promote products derived from this Software without specific +// prior written permission. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE +// SOFTWARE. //===----------------------------------------------------------------------===// // // This class implements a disassembler of a memory block, given a function diff --git a/src/flisp/LICENSE b/src/flisp/LICENSE new file mode 100644 index 00000000000000..34860f4ba63d4f --- /dev/null +++ b/src/flisp/LICENSE @@ -0,0 +1,26 @@ +Copyright (c) 2009 Jeff Bezanson + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the author nor the names of any contributors may be used to + endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/src/jitlayers.cpp b/src/jitlayers.cpp index 92af6ae460004c..5717bcced90bf8 100644 --- a/src/jitlayers.cpp +++ b/src/jitlayers.cpp @@ -1,7 +1,5 @@ // This file is a part of Julia. License is MIT: https://julialang.org/license -// Except for parts of this file which were copied from LLVM, under the UIUC license (marked below). - #include "llvm-version.h" #include "platform.h" From 2ebbb2b3a0b54eae66549bd058ae334cb3642e50 Mon Sep 17 00:00:00 2001 From: Philipp Gabler Date: Wed, 11 Aug 2021 22:01:06 +0200 Subject: [PATCH 047/135] Fix firstindex in replace_ref_begin_end (fixes #41630) (#41695) --- base/views.jl | 2 +- test/offsetarray.jl | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/base/views.jl b/base/views.jl index f60dc04094a430..e26359a5c9fd76 100644 --- a/base/views.jl +++ b/base/views.jl @@ -42,7 +42,7 @@ function replace_ref_begin_end_!(ex, withex) n = 1 J = lastindex(ex.args) for j = 2:J - exj, used = replace_ref_begin_end_!(ex.args[j], (:($firstindex($S)),:($lastindex($S,$n)))) + exj, used = replace_ref_begin_end_!(ex.args[j], (:($firstindex($S,$n)),:($lastindex($S,$n)))) used_S |= used ex.args[j] = exj if isa(exj,Expr) && exj.head === :... diff --git a/test/offsetarray.jl b/test/offsetarray.jl index 1c7985c37256bd..7621e140136275 100644 --- a/test/offsetarray.jl +++ b/test/offsetarray.jl @@ -801,3 +801,24 @@ end @test reshape(a, :) === a @test reshape(a, (:,)) === a end + +@testset "issue #41630: replace_ref_begin_end!/@view on offset-like arrays" begin + x = OffsetArray([1 2; 3 4], -10:-9, 9:10) # 2×2 OffsetArray{...} with indices -10:-9×9:10 + + # begin/end with offset indices + @test (@view x[begin, 9])[] == 1 + @test (@view x[-10, end])[] == 2 + @test (@view x[-9, begin])[] == 3 + @test (@view x[end, 10])[] == 4 + @test (@view x[begin, begin])[] == 1 + @test (@view x[begin, end])[] == 2 + @test (@view x[end, begin])[] == 3 + @test (@view x[end, end])[] == 4 + + # nested usages of begin/end + y = OffsetArray([-10, -9], (5,)) + @test (@view x[begin, -y[end]])[] == 1 + @test (@view x[y[begin], end])[] == 2 + @test (@view x[end, -y[end]])[] == 3 + @test (@view x[y[end], end])[] == 4 +end From 48ed43fc8e47d1e0cbe768cb4b691eaba697eebc Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Thu, 12 Aug 2021 22:54:09 +0900 Subject: [PATCH 048/135] improve `@something` hygine (#41797) * improve intermediate inferrability of `@something` ```julia let x::Union{T,Nothing} if (val = x) !== nothing # can't narrow down to `val::T` here because the type constraint # is imposed on `x` return val end end ``` * Update base/some.jl Co-authored-by: Curtis Vogt * improve escape and add test * Update test/some.jl Co-authored-by: Curtis Vogt * Update base/some.jl Co-authored-by: Curtis Vogt Co-authored-by: Curtis Vogt --- base/some.jl | 6 +++--- test/some.jl | 5 +++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/base/some.jl b/base/some.jl index 58280fe7273524..8be58739a4df41 100644 --- a/base/some.jl +++ b/base/some.jl @@ -138,8 +138,8 @@ true macro something(args...) expr = :(nothing) for arg in reverse(args) - expr = :((val = $arg) !== nothing ? val : $expr) + expr = :(val = $(esc(arg)); val !== nothing ? val : ($expr)) end - return esc(:(something(let val; $expr; end))) + something = GlobalRef(Base, :something) + return :($something($expr)) end - diff --git a/test/some.jl b/test/some.jl index b2111c8b86085e..27d50ca354a494 100644 --- a/test/some.jl +++ b/test/some.jl @@ -87,6 +87,11 @@ end @test @something(1, error("failed")) === 1 @test_throws ErrorException @something(nothing, error("failed")) + + # Ensure that the internal variable doesn't conflict with a user defined variable + @test let val = 1 + @something(val) + end == 1 end # issue #26927 From 79e2f2b0c81e7f1eb1b1f4cc46c5ee815800db15 Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Thu, 12 Aug 2021 17:50:53 +0200 Subject: [PATCH 049/135] clarify that test macro throws outside a testset if it fails (#41756) --- stdlib/Test/src/Test.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/stdlib/Test/src/Test.jl b/stdlib/Test/src/Test.jl index 461c48026944e5..b4f08b8e00d5dc 100644 --- a/stdlib/Test/src/Test.jl +++ b/stdlib/Test/src/Test.jl @@ -347,9 +347,10 @@ end @test ex broken=true @test ex skip=true -Tests that the expression `ex` evaluates to `true`. -Returns a `Pass` `Result` if it does, a `Fail` `Result` if it is +Test that the expression `ex` evaluates to `true`. +If executed inside a `@testset`, return a `Pass` `Result` if it does, a `Fail` `Result` if it is `false`, and an `Error` `Result` if it could not be evaluated. +If executed outside a `@testset`, throw an exception instead of returning `Fail` or `Error`. # Examples ```jldoctest From 01d439e7e1d304903ccf2e37b47acea3d791238f Mon Sep 17 00:00:00 2001 From: Dilum Aluthge Date: Thu, 12 Aug 2021 13:29:12 -0400 Subject: [PATCH 050/135] CI (Buildkite): `llvmpasses`: use the latest rootfs image (#41864) --- .buildkite/pipelines/main/misc/llvmpasses.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.buildkite/pipelines/main/misc/llvmpasses.yml b/.buildkite/pipelines/main/misc/llvmpasses.yml index eed2f957855bb2..a012ace41acffa 100644 --- a/.buildkite/pipelines/main/misc/llvmpasses.yml +++ b/.buildkite/pipelines/main/misc/llvmpasses.yml @@ -33,8 +33,8 @@ steps: - 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" + rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v3.8/package_linux.x86_64.tar.gz + rootfs_treehash: "84a323ae8fcc724f8ea5aca5901bbbf4bda3e519" uid: 1000 gid: 1000 workspaces: From f19b9a20dde2688c642b7dd709b5d9446e4df2f6 Mon Sep 17 00:00:00 2001 From: t-bltg <13423344+t-bltg@users.noreply.github.com> Date: Thu, 12 Aug 2021 21:36:18 +0200 Subject: [PATCH 051/135] MINSIGSTKSZ is no longer constant in glibc (#41860) MINSIGSTKSZ is redefined to sysconf(_SC_MINSIGSTKSZ) starting from glibc 2.34 Co-authored-by: t-bltg --- src/task.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/task.c b/src/task.c index c3ac26fbcf5119..d5ab6258637c6a 100644 --- a/src/task.c +++ b/src/task.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include "julia.h" @@ -67,8 +68,8 @@ static inline void tsan_switch_to_ctx(void *state) { // empirically, jl_finish_task needs about 64k stack space to infer/run // and additionally, gc-stack reserves 64k for the guard pages -#if defined(MINSIGSTKSZ) && MINSIGSTKSZ > 131072 -#define MINSTKSZ MINSIGSTKSZ +#if defined(MINSIGSTKSZ) +#define MINSTKSZ (MINSIGSTKSZ > 131072 ? MINSIGSTKSZ : 131072) #else #define MINSTKSZ 131072 #endif From 73e552200372781c80045776d087d0c82707163f Mon Sep 17 00:00:00 2001 From: Atsushi Sakai Date: Sat, 14 Aug 2021 03:33:03 +0900 Subject: [PATCH 052/135] nothing comparison improvement (#41881) --- stdlib/Distributed/src/managers.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stdlib/Distributed/src/managers.jl b/stdlib/Distributed/src/managers.jl index 08686fc2a0b87d..91a27aa95cb980 100644 --- a/stdlib/Distributed/src/managers.jl +++ b/stdlib/Distributed/src/managers.jl @@ -183,7 +183,7 @@ function parse_machine(machine::AbstractString) if machine[begin] == '[' # ipv6 bracket notation (RFC 2732) ipv6_end = findlast(']', machine) - if ipv6_end == nothing + if ipv6_end === nothing throw(ArgumentError("invalid machine definition format string: invalid port format \"$machine_def\"")) end hoststr = machine[begin+1 : prevind(machine,ipv6_end)] @@ -201,7 +201,7 @@ function parse_machine(machine::AbstractString) portstr = machine_def[2] portnum = tryparse(Int, portstr) - if portnum == nothing + if portnum === nothing msg = "invalid machine definition format string: invalid port format \"$machine_def\"" throw(ArgumentError(msg)) end From 6bb978eb3f743c6e6a7f1da6dd7a82419f701e33 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Sat, 14 Aug 2021 15:03:13 +0900 Subject: [PATCH 053/135] optimizer: minor code refactor (#41886) --- base/compiler/optimize.jl | 17 ++++++++--------- base/compiler/ssair/inlining.jl | 21 ++++++++++----------- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/base/compiler/optimize.jl b/base/compiler/optimize.jl index 349ed52c015291..1898aa8b757782 100644 --- a/base/compiler/optimize.jl +++ b/base/compiler/optimize.jl @@ -101,16 +101,15 @@ function OptimizationState(linfo::MethodInstance, params::OptimizationParams, in end function ir_to_codeinf!(opt::OptimizationState) - optdef = opt.linfo.def - replace_code_newstyle!(opt.src, opt.ir::IRCode, isa(optdef, Method) ? Int(optdef.nargs) : 0) + (; linfo, src) = opt + optdef = linfo.def + replace_code_newstyle!(src, opt.ir::IRCode, isa(optdef, Method) ? Int(optdef.nargs) : 0) opt.ir = nothing - let src = opt.src::CodeInfo - widen_all_consts!(src) - src.inferred = true - # finish updating the result struct - validate_code_in_debug_mode(opt.linfo, src, "optimized") - return src - end + widen_all_consts!(src) + src.inferred = true + # finish updating the result struct + validate_code_in_debug_mode(linfo, src, "optimized") + return src end ############# diff --git a/base/compiler/ssair/inlining.jl b/base/compiler/ssair/inlining.jl index d523d64926876e..5bbf576d9f5364 100644 --- a/base/compiler/ssair/inlining.jl +++ b/base/compiler/ssair/inlining.jl @@ -720,20 +720,19 @@ function compileable_specialization(et::Union{EdgeTracker, Nothing}, (; linfo):: end function resolve_todo(todo::InliningTodo, state::InliningState) - spec = todo.spec::DelayedInliningSpec + (; match) = todo.spec::DelayedInliningSpec #XXX: update_valid_age!(min_valid[1], max_valid[1], sv) isconst, src = false, nothing - if isa(spec.match, InferenceResult) - let inferred_src = spec.match.src - if isa(inferred_src, Const) - if !is_inlineable_constant(inferred_src.val) - return compileable_specialization(state.et, spec.match) - end - isconst, src = true, quoted(inferred_src.val) - else - isconst, src = false, inferred_src + if isa(match, InferenceResult) + inferred_src = match.src + if isa(inferred_src, Const) + if !is_inlineable_constant(inferred_src.val) + return compileable_specialization(state.et, match) end + isconst, src = true, quoted(inferred_src.val) + else + isconst, src = false, inferred_src end else linfo = get(state.mi_cache, todo.mi, nothing) @@ -761,7 +760,7 @@ function resolve_todo(todo::InliningTodo, state::InliningState) end if src === nothing - return compileable_specialization(et, spec.match) + return compileable_specialization(et, match) end if isa(src, IRCode) From 6f8bb64fe9311795183037a2612d0498d3b7bfd6 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Sat, 14 Aug 2021 21:56:41 +0900 Subject: [PATCH 054/135] `AbstractInterpreter`: remove dead logic within `transform_result_for_cache` (#41884) --- base/compiler/typeinfer.jl | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/base/compiler/typeinfer.jl b/base/compiler/typeinfer.jl index 1d2559cf10c3a7..a3895c380f8bd0 100644 --- a/base/compiler/typeinfer.jl +++ b/base/compiler/typeinfer.jl @@ -354,16 +354,10 @@ end function transform_result_for_cache(interp::AbstractInterpreter, linfo::MethodInstance, valid_worlds::WorldRange, @nospecialize(inferred_result)) - local const_flags::Int32 # If we decided not to optimize, drop the OptimizationState now. # External interpreters can override as necessary to cache additional information if inferred_result isa OptimizationState - opt = inferred_result - if isa(opt.src, CodeInfo) - inferred_result = ir_to_codeinf!(opt) - else - inferred_result = opt.src - end + inferred_result = ir_to_codeinf!(inferred_result) end if inferred_result isa CodeInfo inferred_result.min_world = first(valid_worlds) From 19629d72702d908407eaa14769def8249e4a1e71 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Sat, 14 Aug 2021 09:25:51 -0400 Subject: [PATCH 055/135] don't look for packages in code that isn't going to be run this eval (#41887) --- stdlib/REPL/src/REPL.jl | 1 + stdlib/REPL/test/repl.jl | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/stdlib/REPL/src/REPL.jl b/stdlib/REPL/src/REPL.jl index a815678b7ba521..d2054990ceb81f 100644 --- a/stdlib/REPL/src/REPL.jl +++ b/stdlib/REPL/src/REPL.jl @@ -178,6 +178,7 @@ function check_for_missing_packages_and_run_hooks(ast) end function modules_to_be_loaded(ast, mods = Symbol[]) + ast.head == :quote && return mods # don't search if it's not going to be run during this eval if ast.head in [:using, :import] for arg in ast.args if first(arg.args) isa Symbol # i.e. `Foo` diff --git a/stdlib/REPL/test/repl.jl b/stdlib/REPL/test/repl.jl index 8c4ee75850fbff..8d67be4b773d2e 100644 --- a/stdlib/REPL/test/repl.jl +++ b/stdlib/REPL/test/repl.jl @@ -1355,6 +1355,11 @@ end mods = REPL.modules_to_be_loaded(Base.parse_input_line("using Core")) @test isempty(mods) + mods = REPL.modules_to_be_loaded(Base.parse_input_line(":(using Foo)")) + @test isempty(mods) + mods = REPL.modules_to_be_loaded(Base.parse_input_line("ex = :(using Foo)")) + @test isempty(mods) + mods = REPL.modules_to_be_loaded(Base.parse_input_line("# comment")) @test isempty(mods) mods = REPL.modules_to_be_loaded(Base.parse_input_line("Foo")) From 8cad32b2e27e3346b173dc4c7eddc083a639052b Mon Sep 17 00:00:00 2001 From: Mark Kittisopikul Date: Sat, 14 Aug 2021 09:41:53 -0400 Subject: [PATCH 056/135] Add hint for :help to REPL.REPLCompletions.UndefVarError_hint (#41754) --- stdlib/REPL/src/REPLCompletions.jl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/stdlib/REPL/src/REPLCompletions.jl b/stdlib/REPL/src/REPLCompletions.jl index ba33c5f1593afd..77d5d87e41b8cf 100644 --- a/stdlib/REPL/src/REPLCompletions.jl +++ b/stdlib/REPL/src/REPLCompletions.jl @@ -907,6 +907,10 @@ function UndefVarError_hint(io::IO, ex::UndefVarError) print(io, "\nsuggestion: Use `||` for short-circuiting boolean OR.") elseif var === :and print(io, "\nsuggestion: Use `&&` for short-circuiting boolean AND.") + elseif var === :help + println(io) + # Show friendly help message when user types help or help() and help is undefined + show(io, MIME("text/plain"), Base.Docs.parsedoc(Base.Docs.keywords[:help])) end end From 5453b6a46eac30ead07ae9fe059bceba658ea964 Mon Sep 17 00:00:00 2001 From: arfy slowy Date: Sun, 15 Aug 2021 20:20:15 +0700 Subject: [PATCH 057/135] fix: typo spelling grammar (#41883) --- base/compiler/tfuncs.jl | 2 +- src/cgutils.cpp | 4 ++-- src/features_x86.h | 2 +- src/gf.c | 2 +- src/interpreter.c | 2 +- src/llvm-late-gc-lowering.cpp | 2 +- src/llvm-lower-handlers.cpp | 2 +- test/compiler/inference.jl | 2 +- test/compiler/irpasses.jl | 2 +- test/show.jl | 2 +- 10 files changed, 11 insertions(+), 11 deletions(-) diff --git a/base/compiler/tfuncs.jl b/base/compiler/tfuncs.jl index b7d280cc15c1b7..a43c9dd9afff10 100644 --- a/base/compiler/tfuncs.jl +++ b/base/compiler/tfuncs.jl @@ -1177,7 +1177,7 @@ function apply_type_nothrow(argtypes::Array{Any, 1}, @nospecialize(rt)) else return false end - # We know the apply_type is well formed. Oherwise our rt would have been + # We know the apply_type is well formed. Otherwise our rt would have been # Bottom (or Type). (headtype === Union) && return true isa(rt, Const) && return true diff --git a/src/cgutils.cpp b/src/cgutils.cpp index a453393bbd2cc3..95bb7f46a21e5d 100644 --- a/src/cgutils.cpp +++ b/src/cgutils.cpp @@ -234,7 +234,7 @@ static Value *julia_pgv(jl_codectx_t &ctx, const char *cname, void *addr) false, GlobalVariable::PrivateLinkage, NULL, localname); // LLVM passes sometimes strip metadata when moving load around - // since the load at the new location satisfy the same condition as the origional one. + // since the load at the new location satisfy the same condition as the original one. // Mark the global as constant to LLVM code using our own metadata // which is much less likely to be striped. gv->setMetadata("julia.constgv", MDNode::get(gv->getContext(), None)); @@ -2407,7 +2407,7 @@ static Value *emit_arrayptr_internal(jl_codectx_t &ctx, const jl_cgval_t &tinfo, ctx.builder.CreateStructGEP(jl_array_llvmt, emit_bitcast(ctx, t, jl_parray_llvmt), 0); // index (not offset) of data field in jl_parray_llvmt - // Normally allocated array of 0 dimention always have a inline pointer. + // Normally allocated array of 0 dimension always have a inline pointer. // However, we can't rely on that here since arrays can also be constructed from C pointers. MDNode *tbaa = arraytype_constshape(tinfo.typ) ? tbaa_const : tbaa_arrayptr; PointerType *PT = cast(addr->getType()); diff --git a/src/features_x86.h b/src/features_x86.h index ad6a5eb1e515ae..3ef71fb217db69 100644 --- a/src/features_x86.h +++ b/src/features_x86.h @@ -33,7 +33,7 @@ JL_FEATURE_DEF(bmi, 32 * 2 + 3, 0) // JL_FEATURE_DEF(hle, 32 * 2 + 4, 0) // Not used and gone in LLVM 5.0 JL_FEATURE_DEF(avx2, 32 * 2 + 5, 0) JL_FEATURE_DEF(bmi2, 32 * 2 + 8, 0) -// JL_FEATURE_DEF(invpcid, 32 * 2 + 10, 0) // Priviledged instruction +// JL_FEATURE_DEF(invpcid, 32 * 2 + 10, 0) // Privileged instruction JL_FEATURE_DEF(rtm, 32 * 2 + 11, 0) // JL_FEATURE_DEF(mpx, 32 * 2 + 14, 0) // Deprecated in LLVM 10.0 JL_FEATURE_DEF(avx512f, 32 * 2 + 16, 0) diff --git a/src/gf.c b/src/gf.c index 41381ccc5178e8..52180279ab5c2b 100644 --- a/src/gf.c +++ b/src/gf.c @@ -1351,7 +1351,7 @@ static void invalidate_external(jl_method_instance_t *mi, size_t max_world) { jl_printf((JL_STREAM*)STDERR_FILENO, "error in invalidation callback: "); jl_static_show((JL_STREAM*)STDERR_FILENO, jl_current_exception()); jl_printf((JL_STREAM*)STDERR_FILENO, "\n"); - jlbacktrace(); // writen to STDERR_FILENO + jlbacktrace(); // written to STDERR_FILENO } } } diff --git a/src/interpreter.c b/src/interpreter.c index 7858bd6ddc4eae..1ae6507ef334ee 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -516,7 +516,7 @@ static jl_value_t *eval_body(jl_array_t *stmts, interpreter_state *s, size_t ip, s->continue_at = 0; continue; } - else { // a real exeception + else { // a real exception ip = catch_ip; continue; } diff --git a/src/llvm-late-gc-lowering.cpp b/src/llvm-late-gc-lowering.cpp index d8ad3d62d4cc1d..0aac7638be0d22 100644 --- a/src/llvm-late-gc-lowering.cpp +++ b/src/llvm-late-gc-lowering.cpp @@ -1573,7 +1573,7 @@ State LateLowerGCFrame::LocalScan(Function &F) { for (Use &U : CI->arg_operands()) { // Find all callee rooted arguments. // Record them instead of simply remove them from live values here - // since they can be useful during refinment + // since they can be useful during refinement // (e.g. to remove roots of objects that are refined to these) Value *V = U; if (isa(V) || !isa(V->getType()) || diff --git a/src/llvm-lower-handlers.cpp b/src/llvm-lower-handlers.cpp index 7382f3b74c0801..ae5a6f3b0c11d0 100644 --- a/src/llvm-lower-handlers.cpp +++ b/src/llvm-lower-handlers.cpp @@ -176,7 +176,7 @@ bool LowerExcHandlers::runOnFunction(Function &F) { /* Step 2: EH Frame lowering */ // Allocate stack space for each handler. We allocate these as separate - // allocas so the optimizer can later merge and reaarange them if it wants + // allocas so the optimizer can later merge and rearrange them if it wants // to. Value *handler_sz = ConstantInt::get(Type::getInt32Ty(F.getContext()), sizeof(jl_handler_t)); diff --git a/test/compiler/inference.jl b/test/compiler/inference.jl index c03bb25358e2e5..6bd8df57e8a8ab 100644 --- a/test/compiler/inference.jl +++ b/test/compiler/inference.jl @@ -2669,7 +2669,7 @@ const DenseIdx = Union{IntRange,Integer} foo_26724((result..., length(r)), I...) @test @inferred(foo_26724((), 1:4, 1:5, 1:6)) === (4, 5, 6) -# Non uniformity in expresions with PartialTypeVar +# Non uniformity in expressions with PartialTypeVar @test Core.Compiler.:⊑(Core.Compiler.PartialTypeVar(TypeVar(:N), true, true), TypeVar) let N = TypeVar(:N) @test Core.Compiler.apply_type_nothrow([Core.Compiler.Const(NTuple), diff --git a/test/compiler/irpasses.jl b/test/compiler/irpasses.jl index 3be15ef9cc3172..c4e3023184c13c 100644 --- a/test/compiler/irpasses.jl +++ b/test/compiler/irpasses.jl @@ -128,7 +128,7 @@ let nt = (a=1, b=2) @test_throws ArgumentError blah31139(nt) end -# Expr(:new) annoted as PartialStruct +# Expr(:new) annotated as PartialStruct struct FooPartial x y diff --git a/test/show.jl b/test/show.jl index 1552214d2516eb..cb9e2e9fc3b8fc 100644 --- a/test/show.jl +++ b/test/show.jl @@ -1825,7 +1825,7 @@ end @test showstr(Dict(true=>false)) == "Dict{Bool, Bool}(1 => 0)" @test showstr(Dict((1 => 2) => (3 => 4))) == "Dict((1 => 2) => (3 => 4))" - # issue #27979 (dislaying arrays of pairs containing arrays as first member) + # issue #27979 (displaying arrays of pairs containing arrays as first member) @test replstr([[1.0]=>1.0]) == "1-element Vector{Pair{Vector{Float64}, Float64}}:\n [1.0] => 1.0" # issue #28159 From b40ae6b79b51c9c83a947e4317e36f957c59ae0b Mon Sep 17 00:00:00 2001 From: Elliot Saba Date: Sun, 15 Aug 2021 08:20:19 -0700 Subject: [PATCH 058/135] [LinearAlgebra] flesh out LBT API a bit more (#41452) This adds `lbt_find_backing_library()`, which is a useful debugging routine to allow advanced users/package authors to query LBT to determine which backing BLAS library will service a particular BLAS call. It also exposes the "footgun API", which allows users to directly set/get forwarding on a per-function basis. Because this has the ability to generate truly bizarre setups, we do not advertise this capability broadly (simply using `lbt_forward()` should be enough for most usecases) however it's nice to have wrapped. --- stdlib/LinearAlgebra/src/blas.jl | 2 +- stdlib/LinearAlgebra/src/lbt.jl | 74 +++++++++++++++++++++++++++++--- 2 files changed, 69 insertions(+), 7 deletions(-) diff --git a/stdlib/LinearAlgebra/src/blas.jl b/stdlib/LinearAlgebra/src/blas.jl index 327beb020901ba..c96fc9b965b1e9 100644 --- a/stdlib/LinearAlgebra/src/blas.jl +++ b/stdlib/LinearAlgebra/src/blas.jl @@ -79,7 +79,7 @@ import LinearAlgebra: BlasReal, BlasComplex, BlasFloat, BlasInt, DimensionMismat include("lbt.jl") """ -get_config() + get_config() Return an object representing the current `libblastrampoline` configuration. diff --git a/stdlib/LinearAlgebra/src/lbt.jl b/stdlib/LinearAlgebra/src/lbt.jl index 67ce521a9aa7e1..b1a2dc24b34492 100644 --- a/stdlib/LinearAlgebra/src/lbt.jl +++ b/stdlib/LinearAlgebra/src/lbt.jl @@ -17,6 +17,7 @@ const LBT_INTERFACE_MAP = Dict( LBT_INTERFACE_ILP64 => :ilp64, LBT_INTERFACE_UNKNOWN => :unknown, ) +const LBT_INV_INTERFACE_MAP = Dict(v => k for (k, v) in LBT_INTERFACE_MAP) const LBT_F2C_PLAIN = 0 const LBT_F2C_REQUIRED = 1 @@ -26,6 +27,7 @@ const LBT_F2C_MAP = Dict( LBT_F2C_REQUIRED => :required, LBT_F2C_UNKNOWN => :unknown, ) +const LBT_INV_F2C_MAP = Dict(v => k for (k, v) in LBT_F2C_MAP) struct LBTLibraryInfo libname::String @@ -164,14 +166,74 @@ function lbt_get_default_func() return ccall((:lbt_get_default_func, libblastrampoline), Ptr{Cvoid}, ()) end -#= -Don't define footgun API (yet) +""" + lbt_find_backing_library(symbol_name, interface; config::LBTConfig = lbt_get_config()) -function lbt_get_forward(symbol_name, interface, f2c = LBT_F2C_PLAIN) - return ccall((:lbt_get_forward, libblastrampoline), Ptr{Cvoid}, (Cstring, Int32, Int32), symbol_name, interface, f2c) +Return the `LBTLibraryInfo` that represents the backing library for the given symbol +exported from libblastrampoline. This allows us to discover which library will service +a particular BLAS call from Julia code. This method returns `nothing` if either of the +following conditions are met: + + * No loaded library exports the desired symbol (the default function will be called) + * The symbol was set via `lbt_set_forward()`, which does not track library provenance. + +If the given `symbol_name` is not contained within the list of exported symbols, an +`ArgumentError` will be thrown. +""" +function lbt_find_backing_library(symbol_name, interface::Symbol; + config::LBTConfig = lbt_get_config()) + if interface ∉ (:ilp64, :lp64) + throw(Argument("Invalid interface specification: '$(interface)'")) + end + symbol_idx = findfirst(s -> s == symbol_name, config.exported_symbols) + if symbol_idx === nothing + throw(ArgumentError("Invalid exported symbol name '$(symbol_name)'")) + end + # Convert to zero-indexed + symbol_idx -= 1 + + forward_byte_offset = div(symbol_idx, 8) + forward_byte_mask = 1 << mod(symbol_idx, 8) + for lib in filter(l -> l.interface == interface, config.loaded_libs) + if lib.active_forwards[forward_byte_offset+1] & forward_byte_mask != 0x00 + return lib + end + end + + # No backing library was found + return nothing end + +## NOTE: Manually setting forwards is referred to as the 'footgun API'. It allows truly +## bizarre and complex setups to be created. If you run into strange errors while using +## it, the first thing you should ask yourself is whether you've set things up properly. function lbt_set_forward(symbol_name, addr, interface, f2c = LBT_F2C_PLAIN; verbose::Bool = false) - return ccall((:lbt_set_forward, libblastrampoline), Int32, (Cstring, Ptr{Cvoid}, Int32, Int32, Int32), symbol_name, addr, interface, f2c, verbose ? 1 : 0) + return ccall( + (:lbt_set_forward, libblastrampoline), + Int32, + (Cstring, Ptr{Cvoid}, Int32, Int32, Int32), + string(symbol_name), + addr, + Int32(interface), + Int32(f2c), + verbose ? Int32(1) : Int32(0), + ) +end +function lbt_set_forward(symbol_name, addr, interface::Symbol, f2c::Symbol = :plain; kwargs...) + return lbt_set_forward(symbol_name, addr, LBT_INV_INTERFACE_MAP[interface], LBT_INV_F2C_MAP[f2c]; kwargs...) +end + +function lbt_get_forward(symbol_name, interface, f2c = LBT_F2C_PLAIN) + return ccall( + (:lbt_get_forward, libblastrampoline), + Ptr{Cvoid}, + (Cstring, Int32, Int32), + string(symbol_name), + Int32(interface), + Int32(f2c), + ) +end +function lbt_get_forward(symbol_name, interface::Symbol, f2c::Symbol = :plain) + return lbt_get_forward(symbol_name, LBT_INV_INTERFACE_MAP[interface], LBT_INV_F2C_MAP[f2c]) end -=# \ No newline at end of file From 398d1a0dbc9107822a77eabfe1e1e4b094f10d39 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Tue, 17 Aug 2021 02:20:54 +0900 Subject: [PATCH 059/135] fix `current_exceptions` docstring and annotate arguments (#41897) --- base/error.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/base/error.jl b/base/error.jl index 9116d006189001..0976b9c28fa8cb 100644 --- a/base/error.jl +++ b/base/error.jl @@ -128,7 +128,7 @@ struct ExceptionStack <: AbstractArray{Any,1} end """ - current_exceptions(task=current_task(); [inclue_bt=true]) + current_exceptions(task::Task=current_task(); [backtrace::Bool=true]) Get the stack of exceptions currently being handled. For nested catch blocks there may be more than one current exception in which case the most recently @@ -145,7 +145,7 @@ uncaught exceptions. This function went by the experiemental name `catch_stack()` in Julia 1.1–1.6, and had a plain Vector-of-tuples as a return type. """ -function current_exceptions(task=current_task(); backtrace=true) +function current_exceptions(task::Task=current_task(); backtrace::Bool=true) raw = ccall(:jl_get_excstack, Any, (Any,Cint,Cint), task, backtrace, typemax(Cint))::Vector{Any} formatted = Any[] stride = backtrace ? 3 : 1 From ab600f8ce704cafd519581ad62858d00f82a40d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gunnar=20Farneb=C3=A4ck?= Date: Mon, 16 Aug 2021 19:32:52 +0200 Subject: [PATCH 060/135] [REPL] 0nly do NFD normalization for latex tab-completion help if no match without it (#41870) --- stdlib/REPL/src/docview.jl | 8 ++++++-- test/docs.jl | 2 ++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/stdlib/REPL/src/docview.jl b/stdlib/REPL/src/docview.jl index 2e5fc361d8cbc9..f4467b3e787bc0 100644 --- a/stdlib/REPL/src/docview.jl +++ b/stdlib/REPL/src/docview.jl @@ -403,9 +403,13 @@ function symbol_latex(s::String) return get(symbols_latex, s, "") end function repl_latex(io::IO, s::String) - # decompose NFC-normalized identifier to match tab-completion input - s = normalize(s, :NFD) latex = symbol_latex(s) + if isempty(latex) + # Decompose NFC-normalized identifier to match tab-completion + # input if the first search came up empty. + s = normalize(s, :NFD) + latex = symbol_latex(s) + end if !isempty(latex) print(io, "\"") printstyled(io, s, color=:cyan) diff --git a/test/docs.jl b/test/docs.jl index 05442df9d4cbef..41c3746d7476f3 100644 --- a/test/docs.jl +++ b/test/docs.jl @@ -1271,6 +1271,8 @@ end # issue #36378 (\u1e8b and x\u307 are the fully composed and decomposed forms of ẋ, respectively) @test sprint(repl_latex, "\u1e8b") == "\"x\u307\" can be typed by x\\dot\n\n" +# issue 39814 +@test sprint(repl_latex, "\u2209") == "\"\u2209\" can be typed by \\notin\n\n" # issue #15684 begin From 9ae49bcca34b0ef28c094cc2a3400e1617064589 Mon Sep 17 00:00:00 2001 From: Petr Vana Date: Mon, 16 Aug 2021 19:33:49 +0200 Subject: [PATCH 061/135] docs: add v1.7 compat for `@atomic` and fix links (#41873) --- base/expr.jl | 15 ++++++++++++--- doc/src/manual/multi-threading.md | 3 +++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/base/expr.jl b/base/expr.jl index e0304f7f7382bb..86d77fc1e4f88f 100644 --- a/base/expr.jl +++ b/base/expr.jl @@ -505,7 +505,7 @@ result into the field in the first argument and return the values `(old, new)`. This operation translates to a `modifyproperty!(a.b, :x, func, arg2)` call. -See [atomics](#man-atomics) in the manual for more details. +See [Per-field atomics](@ref man-atomics) section in the manual for more details. ```jldoctest julia> mutable struct Atomic{T}; @atomic x::T; end @@ -534,6 +534,9 @@ julia> @atomic max(a.x, 10) # change field x of a to the max value, with sequent julia> @atomic a.x max 5 # again change field x of a to the max value, with sequential consistency 10 => 10 ``` + +!!! compat "Julia 1.7" + This functionality requires at least Julia 1.7. """ macro atomic(ex) if !isa(ex, Symbol) && !is_expr(ex, :(::)) @@ -601,7 +604,7 @@ Stores `new` into `a.b.x` and returns the old value of `a.b.x`. This operation translates to a `swapproperty!(a.b, :x, new)` call. -See [atomics](#man-atomics) in the manual for more details. +See [Per-field atomics](@ref man-atomics) section in the manual for more details. ```jldoctest julia> mutable struct Atomic{T}; @atomic x::T; end @@ -615,6 +618,9 @@ julia> @atomicswap a.x = 2+2 # replace field x of a with 4, with sequential cons julia> @atomic a.x # fetch field x of a, with sequential consistency 4 ``` + +!!! compat "Julia 1.7" + This functionality requires at least Julia 1.7. """ macro atomicswap(order, ex) order isa QuoteNode || (order = esc(order)) @@ -644,7 +650,7 @@ replacement was completed. This operation translates to a `replaceproperty!(a.b, :x, expected, desired)` call. -See [atomics](#man-atomics) in the manual for more details. +See [Per-field atomics](@ref man-atomics) section in the manual for more details. ```jldoctest julia> mutable struct Atomic{T}; @atomic x::T; end @@ -669,6 +675,9 @@ julia> @atomicreplace a.x xchg julia> @atomic a.x # fetch field x of a, with sequential consistency 0 ``` + +!!! compat "Julia 1.7" + This functionality requires at least Julia 1.7. """ macro atomicreplace(success_order, fail_order, ex, old_new) fail_order isa QuoteNode || (fail_order = esc(fail_order)) diff --git a/doc/src/manual/multi-threading.md b/doc/src/manual/multi-threading.md index 658bec21bbfb96..246fab74f8fe73 100644 --- a/doc/src/manual/multi-threading.md +++ b/doc/src/manual/multi-threading.md @@ -249,6 +249,9 @@ orderings (:monotonic, :acquire, :release, :acquire\_release, or with an atomic ordering constraint, or will be done with monotonic (relaxed) ordering if unspecified. +!!! compat "Julia 1.7" + Per-field atomics requires at least Julia 1.7. + ## Side effects and mutable function arguments From cd43dda8a689e65e66232b7b08f927d0a8604554 Mon Sep 17 00:00:00 2001 From: Sebastian Stock <42280794+sostock@users.noreply.github.com> Date: Mon, 16 Aug 2021 19:36:17 +0200 Subject: [PATCH 062/135] searchsorted: add tests for issue #10966 (#41874) --- test/sorting.jl | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/test/sorting.jl b/test/sorting.jl index 718a7f819e2035..8946051c73a180 100644 --- a/test/sorting.jl +++ b/test/sorting.jl @@ -142,6 +142,26 @@ end @test searchsortedlast(500:1.0:600, 1.0e20) == 101 end + @testset "issue 10966" begin + for R in numTypes, T in numTypes + @test searchsortedfirst(R(2):R(2), T(0)) == 1 + @test searchsortedfirst(R(2):R(2), T(2)) == 1 + @test searchsortedfirst(R(2):R(2), T(3)) == 2 + @test searchsortedfirst(R(1):1//2:R(5), T(0)) == 1 + @test searchsortedfirst(R(1):1//2:R(5), T(2)) == 3 + @test searchsortedfirst(R(1):1//2:R(5), T(6)) == 10 + @test searchsortedlast(R(2):R(2), T(0)) == 0 + @test searchsortedlast(R(2):R(2), T(2)) == 1 + @test searchsortedlast(R(2):R(2), T(3)) == 1 + @test searchsortedlast(R(1):1//2:R(5), T(0)) == 0 + @test searchsortedlast(R(1):1//2:R(5), T(2)) == 3 + @test searchsortedlast(R(1):1//2:R(5), T(6)) == 9 + @test searchsorted(R(2):R(2), T(0)) === 1:0 + @test searchsorted(R(2):R(2), T(2)) == 1:1 + @test searchsorted(R(2):R(2), T(3)) === 2:1 + end + end + @testset "issue 32568" begin for R in numTypes, T in numTypes for arr in Any[R[1:5;], R(1):R(5), R(1):2:R(5)] From 3306a8bf1a78c64f84e40094c0f831314429f1ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krystian=20Guli=C5=84ski?= Date: Mon, 16 Aug 2021 20:04:47 +0200 Subject: [PATCH 063/135] [Distributed] Fix finalizer_ref usage of lock/wait resulting in failed task switches (#41846) --- stdlib/Distributed/src/remotecall.jl | 66 ++++++++++++++++++---------- 1 file changed, 44 insertions(+), 22 deletions(-) diff --git a/stdlib/Distributed/src/remotecall.jl b/stdlib/Distributed/src/remotecall.jl index 088b7416f44886..fabcf106860688 100644 --- a/stdlib/Distributed/src/remotecall.jl +++ b/stdlib/Distributed/src/remotecall.jl @@ -84,20 +84,24 @@ end function finalize_ref(r::AbstractRemoteRef) if r.where > 0 # Handle the case of the finalizer having been called manually - if islocked(client_refs) - # delay finalizer for later, when it's not already locked + if trylock(client_refs.lock) # trylock doesn't call wait which causes yields + try + delete!(client_refs.ht, r) # direct removal avoiding locks + if isa(r, RemoteChannel) + send_del_client_no_lock(r) + else + # send_del_client only if the reference has not been set + r.v === nothing && send_del_client_no_lock(r) + r.v = nothing + end + r.where = 0 + finally + unlock(client_refs.lock) + end + else finalizer(finalize_ref, r) return nothing end - delete!(client_refs, r) - if isa(r, RemoteChannel) - send_del_client(r) - else - # send_del_client only if the reference has not been set - r.v === nothing && send_del_client(r) - r.v = nothing - end - r.where = 0 end nothing end @@ -229,13 +233,18 @@ del_client(rr::AbstractRemoteRef) = del_client(remoteref_id(rr), myid()) del_client(id, client) = del_client(PGRP, id, client) function del_client(pg, id, client) lock(client_refs) do - rv = get(pg.refs, id, false) - if rv !== false - delete!(rv.clientset, client) - if isempty(rv.clientset) - delete!(pg.refs, id) - #print("$(myid()) collected $id\n") - end + _del_client(pg, id, client) + end + nothing +end + +function _del_client(pg, id, client) + rv = get(pg.refs, id, false) + if rv !== false + delete!(rv.clientset, client) + if isempty(rv.clientset) + delete!(pg.refs, id) + #print("$(myid()) collected $id\n") end end nothing @@ -259,13 +268,26 @@ 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) + process_worker(rr) end end +function send_del_client_no_lock(rr) + # for gc context to avoid yields + if rr.where == myid() + _del_client(PGRP, remoteref_id(rr), myid()) + elseif id_in_procs(rr.where) # process only if a valid worker + process_worker(rr) + end +end + +function process_worker(rr) + w = worker_from_id(rr.where)::Worker + push!(w.del_msgs, (remoteref_id(rr), myid())) + w.gcflag = true + notify(any_gc_flag) +end + function add_client(id, client) lock(client_refs) do rv = lookup_ref(id) From 5ff9e3ad509d462ccd9321d09fb8e9313634079b Mon Sep 17 00:00:00 2001 From: Mark Kittisopikul Date: Mon, 16 Aug 2021 15:07:27 -0400 Subject: [PATCH 064/135] Add `range(; stop)` and `range(; length)` (#39241) As a single keyword arg only (single positional arg not allowed still) --- NEWS.md | 1 + base/range.jl | 41 +++++++++++++++++++++++++++++++++++++++-- test/ranges.jl | 20 +++++++++++++++++++- 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/NEWS.md b/NEWS.md index cb298402ea88d2..b2e597bb1a3019 100644 --- a/NEWS.md +++ b/NEWS.md @@ -41,6 +41,7 @@ New library features Standard library changes ------------------------ +* `range` accepts either `stop` or `length` as a sole keyword argument ([#39241]) * 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 diff --git a/base/range.jl b/base/range.jl index 4ddecd7bdd91c1..1ab21c3d07d10a 100644 --- a/base/range.jl +++ b/base/range.jl @@ -58,6 +58,9 @@ Valid invocations of range are: * Call `range` with any three of `start`, `step`, `stop`, `length`. * Call `range` with two of `start`, `stop`, `length`. In this case `step` will be assumed to be one. If both arguments are Integers, a [`UnitRange`](@ref) will be returned. +* Call `range` with one of `stop` or `length`. `start` and `step` will be assumed to be one. + +See Extended Help for additional details on the returned type. # Examples ```jldoctest @@ -87,6 +90,15 @@ julia> range(stop=10, step=1, length=5) julia> range(start=1, step=1, stop=10) 1:1:10 + +julia> range(; length = 10) +Base.OneTo(10) + +julia> range(; stop = 6) +Base.OneTo(6) + +julia> range(; stop = 6.5) +1.0:1.0:6.0 ``` If `length` is not specified and `stop - start` is not an integer multiple of `step`, a range that ends before `stop` will be produced. ```jldoctest @@ -103,6 +115,23 @@ To avoid this induced overhead, see the [`LinRange`](@ref) constructor. !!! compat "Julia 1.7" The versions without keyword arguments and `start` as a keyword argument require at least Julia 1.7. + +!!! compat "Julia 1.8" + The versions with `stop` as a sole keyword argument, + or `length` as a sole keyword argument require at least Julia 1.8. + + +# Extended Help + +`range` will produce a `Base.OneTo` when the arguments are Integers and +* Only `length` is provided +* Only `stop` is provided + +`range` will produce a `UnitRange` when the arguments are Integers and +* Only `start` and `stop` are provided +* Only `length` and `stop` are provided + +A `UnitRange` is not produced if `step` is provided even if specified as one. """ function range end @@ -115,8 +144,8 @@ range(;start=nothing, stop=nothing, length::Union{Integer, Nothing}=nothing, ste _range(start, step, stop, length) _range(start::Nothing, step::Nothing, stop::Nothing, len::Nothing) = range_error(start, step, stop, len) -_range(start::Nothing, step::Nothing, stop::Nothing, len::Any ) = range_error(start, step, stop, len) -_range(start::Nothing, step::Nothing, stop::Any , len::Nothing) = range_error(start, step, stop, len) +_range(start::Nothing, step::Nothing, stop::Nothing, len::Any ) = range_length(len) +_range(start::Nothing, step::Nothing, stop::Any , len::Nothing) = range_stop(stop) _range(start::Nothing, step::Nothing, stop::Any , len::Any ) = range_stop_length(stop, len) _range(start::Nothing, step::Any , stop::Nothing, len::Nothing) = range_error(start, step, stop, len) _range(start::Nothing, step::Any , stop::Nothing, len::Any ) = range_error(start, step, stop, len) @@ -131,6 +160,14 @@ _range(start::Any , step::Any , stop::Nothing, len::Any ) = range_start _range(start::Any , step::Any , stop::Any , len::Nothing) = range_start_step_stop(start, step, stop) _range(start::Any , step::Any , stop::Any , len::Any ) = range_error(start, step, stop, len) +# Length as the only argument +range_length(len::Integer) = OneTo(len) + +# Stop as the only argument +range_stop(stop) = range_start_stop(oneunit(stop), stop) +range_stop(stop::Integer) = range_length(stop) + +# Stop and length as the only argument range_stop_length(a::Real, len::Integer) = UnitRange{typeof(a)}(oftype(a, a-len+1), a) range_stop_length(a::AbstractFloat, len::Integer) = range_step_stop_length(oftype(a, 1), a, len) range_stop_length(a, len::Integer) = range_step_stop_length(oftype(a-a, 1), a, len) diff --git a/test/ranges.jl b/test/ranges.jl index 1c31585ece45e0..958add3a9483b4 100644 --- a/test/ranges.jl +++ b/test/ranges.jl @@ -20,6 +20,20 @@ using Base.Checked: checked_length # the next ones use ==, because it changes the eltype @test r == range(first(r), last(r), length(r) ) @test r == range(start=first(r), stop=last(r), length=length(r)) + @test r === range( stop=last(r), length=length(r)) + + r = 1:5 + o = Base.OneTo(5) + let start=first(r), step=step(r), stop=last(r), length=length(r) + @test o === range(; stop ) + @test o === range(; length) + @test r === range(; start, stop ) + @test r === range(; stop, length) + # the next three lines uses ==, because it changes the eltype + @test r == range(; start, stop, length) + @test r == range(; start, step, length) + @test r == range(; stop=Float64(stop)) + end for T = (Int8, Rational{Int16}, UInt32, Float64, Char) @test typeof(range(start=T(5), length=3)) === typeof(range(stop=T(5), length=3)) @@ -1508,8 +1522,12 @@ end @test_throws ArgumentError range(1) @test_throws ArgumentError range(nothing) @test_throws ArgumentError range(1, step=4) - @test_throws ArgumentError range(nothing, length=2) + @test_throws ArgumentError range(; step=1, length=6) + @test_throws ArgumentError range(; step=2, stop=7.5) @test_throws ArgumentError range(1.0, step=0.25, stop=2.0, length=5) + @test_throws ArgumentError range(; stop=nothing) + @test_throws ArgumentError range(; length=nothing) + @test_throws TypeError range(; length=5.5) end @testset "issue #23300#issuecomment-371575548" begin From d612c479f4194a5963e457494c5569c090d44078 Mon Sep 17 00:00:00 2001 From: Anant Thazhemadam <47104651+thazhemadam@users.noreply.github.com> Date: Tue, 17 Aug 2021 01:49:32 +0530 Subject: [PATCH 065/135] file.jl: add a note differentiating `cp` function from `cp` command (#41761) The `cp` function behaves more deterministically than the command and can have serious consequences if `force=true` when `dst` is a directory. Add a note to the docstring mentioning this. --- base/file.jl | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/base/file.jl b/base/file.jl index f9deb5b9fbe482..85450ff2d36450 100644 --- a/base/file.jl +++ b/base/file.jl @@ -359,6 +359,13 @@ If `follow_symlinks=false`, and `src` is a symbolic link, `dst` will be created symbolic link. If `follow_symlinks=true` and `src` is a symbolic link, `dst` will be a copy of the file or directory `src` refers to. Return `dst`. + +!!! note + The `cp` function is different from the `cp` command. The `cp` function always operates on + the assumption that `dst` is a file, while the command does different things depending + on whether `dst` is a directory or a file. + Using `force=true` when `dst` is a directory will result in loss of all the contents present + in the `dst` directory, and `dst` will become a file that has the contents of `src` instead. """ function cp(src::AbstractString, dst::AbstractString; force::Bool=false, follow_symlinks::Bool=false) From e8faf9d17b78cdc61146893f71b7902d9dd80d81 Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Tue, 17 Aug 2021 10:43:36 +0200 Subject: [PATCH 066/135] ensure that the non-REPL precompile code actually get precompiled (#41898) --- contrib/generate_precompile.jl | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/contrib/generate_precompile.jl b/contrib/generate_precompile.jl index 278dda28125594..bb760f70ab8678 100644 --- a/contrib/generate_precompile.jl +++ b/contrib/generate_precompile.jl @@ -250,16 +250,20 @@ function generate_precompile_statements() module $pkgname end """) - tmp = tempname() + tmp_prec = tempname() + tmp_proc = tempname() s = """ pushfirst!(DEPOT_PATH, $(repr(prec_path))); - Base.PRECOMPILE_TRACE_COMPILE[] = $(repr(tmp)); + Base.PRECOMPILE_TRACE_COMPILE[] = $(repr(tmp_prec)); Base.compilecache(Base.PkgId($(repr(pkgname))), $(repr(path))) $precompile_script """ - run(`$(julia_exepath()) -O0 --sysimage $sysimg --startup-file=no -Cnative -e $s`) - for statement in split(read(tmp, String), '\n') - push!(statements, statement) + run(`$(julia_exepath()) -O0 --sysimage $sysimg --trace-compile=$tmp_proc --startup-file=no -Cnative -e $s`) + for f in (tmp_prec, tmp_proc) + for statement in split(read(f, String), '\n') + occursin("Main.", statement) && continue + push!(statements, statement) + end end end From c70db599c2d90e13cf1c8b83247d4f41cea08be3 Mon Sep 17 00:00:00 2001 From: "Tamas K. Papp" Date: Tue, 17 Aug 2021 12:32:04 +0200 Subject: [PATCH 067/135] doc: add section about function types in the Types section (#41855) --- doc/src/manual/types.md | 44 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/doc/src/manual/types.md b/doc/src/manual/types.md index 0be372d4fa6120..949d6f3b8d1a0d 100644 --- a/doc/src/manual/types.md +++ b/doc/src/manual/types.md @@ -1108,6 +1108,50 @@ julia> NoFieldsParam{Int}() === NoFieldsParam{Int}() true ``` +## Types of functions + +Each function has its own type, which is a subtype of `Function`. + +```jldoctest foo41 +julia> foo41(x) = x + 1 +foo41 (generic function with 1 method) + +julia> typeof(foo41) +typeof(foo41) (singleton type of function foo41, subtype of Function) +``` + +Note how `typeof(foo41)` prints as itself. This is merely a convention for printing, as it is a first-class object that can be used like any other value: + +```jldoctest foo41 +julia> T = typeof(foo41) +typeof(foo41) (singleton type of function foo41, subtype of Function) + +julia> T <: Function +true +``` + +Types of functions defined at top-level are singletons. When necessary, you can compare them with [`===`](@ref). + +[Closures](@id man-anonymous-functions) also have their own type, which is usually printed with names that end in `#`. Names and types for functions defined at different locations are distinct, but not guaranteed to be printed the same way across sessions. + +```jldoctest; filter = r"[0-9\.]+" +julia> typeof(x -> x + 1) +var"#9#10" +``` + +Types of closures are not necessarily singletons. + +```jldoctest +julia> addy(y) = x -> x + y +addy (generic function with 1 method) + +julia> Base.issingletontype(addy(1)) +false + +julia> addy(1) === addy(2) +false +``` + ## [`Type{T}` type selectors](@id man-typet-type) For each type `T`, `Type{T}` is an abstract parametric type whose only instance is the From 337cf383c546e67974677f139a33abf1b065393a Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Tue, 17 Aug 2021 20:26:13 +0200 Subject: [PATCH 068/135] add a showerror implementation for InvalidStateException (#41901) --- base/channels.jl | 1 + doc/src/manual/asynchronous-programming.md | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/base/channels.jl b/base/channels.jl index 1557504bbe21e1..31cbd98a2abb26 100644 --- a/base/channels.jl +++ b/base/channels.jl @@ -298,6 +298,7 @@ struct InvalidStateException <: Exception msg::String state::Symbol end +showerror(io::IO, ex::InvalidStateException) = print(io, "InvalidStateException: ", ex.msg) """ put!(c::Channel, v) diff --git a/doc/src/manual/asynchronous-programming.md b/doc/src/manual/asynchronous-programming.md index c0181e775bd05b..4eee0fccf7da2a 100644 --- a/doc/src/manual/asynchronous-programming.md +++ b/doc/src/manual/asynchronous-programming.md @@ -211,7 +211,7 @@ A channel can be visualized as a pipe, i.e., it has a write end and a read end : julia> close(c); julia> put!(c, 2) # `put!` on a closed channel throws an exception. - ERROR: InvalidStateException("Channel is closed.",:closed) + ERROR: InvalidStateException: Channel is closed. Stacktrace: [...] ``` @@ -230,7 +230,7 @@ A channel can be visualized as a pipe, i.e., it has a write end and a read end : 1 julia> take!(c) # No more data available on a closed channel. - ERROR: InvalidStateException("Channel is closed.",:closed) + ERROR: InvalidStateException: Channel is closed. Stacktrace: [...] ``` From b7f77088bda47ed1187d43c3750b5a25a5b70284 Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Tue, 17 Aug 2021 20:26:52 +0200 Subject: [PATCH 069/135] code quote the atomic orderings in the manual (#41902) --- doc/src/manual/multi-threading.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/src/manual/multi-threading.md b/doc/src/manual/multi-threading.md index 246fab74f8fe73..135b5c3a6589e4 100644 --- a/doc/src/manual/multi-threading.md +++ b/doc/src/manual/multi-threading.md @@ -244,8 +244,8 @@ which will later be published formally. Any field in a struct declaration can be decorated with `@atomic`, and then any write must be marked with `@atomic` also, and must use one of the defined atomic -orderings (:monotonic, :acquire, :release, :acquire\_release, or -:sequentially\_consistent). Any read of an atomic field can also be annotated +orderings (`:monotonic`, `:acquire`, `:release`, `:acquire_release`, or +`:sequentially_consistent`). Any read of an atomic field can also be annotated with an atomic ordering constraint, or will be done with monotonic (relaxed) ordering if unspecified. From a03392ad4f3c01abdc5223283028af3523b6b356 Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Tue, 17 Aug 2021 13:53:19 -0500 Subject: [PATCH 070/135] Support `@test_throws` just checking the error message (#41888) With this PR, @test_throws "reducing over an empty collection" reduce(+, ()) allows you to check the displayed error message without caring about the details of which specific Exception subtype is used. The pattern-matching options are the same as for `@test_warn`. Co-authored by: Jameson Nash Co-authored by: Takafumi Arakaki --- NEWS.md | 3 ++ stdlib/Test/src/Test.jl | 64 ++++++++++++++++++++++++++++-------- stdlib/Test/test/runtests.jl | 38 ++++++++++++++++++++- 3 files changed, 91 insertions(+), 14 deletions(-) diff --git a/NEWS.md b/NEWS.md index b2e597bb1a3019..6ac3546e969bb1 100644 --- a/NEWS.md +++ b/NEWS.md @@ -37,6 +37,9 @@ New library functions New library features -------------------- +* `@test_throws "some message" triggers_error()` can now be used to check whether the displayed error text + contains "some message" regardless of the specific exception type. + Regular expressions, lists of strings, and matching functions are also supported. ([#41888) Standard library changes ------------------------ diff --git a/stdlib/Test/src/Test.jl b/stdlib/Test/src/Test.jl index b4f08b8e00d5dc..0c9cfd5ccafd12 100644 --- a/stdlib/Test/src/Test.jl +++ b/stdlib/Test/src/Test.jl @@ -86,8 +86,9 @@ struct Pass <: Result data value source::Union{Nothing,LineNumberNode} - function Pass(test_type::Symbol, orig_expr, data, thrown, source=nothing) - return new(test_type, orig_expr, data, thrown isa String ? "String" : thrown, source) + message_only::Bool + function Pass(test_type::Symbol, orig_expr, data, thrown, source=nothing, message_only=false) + return new(test_type, orig_expr, data, thrown, source, message_only) end end @@ -98,7 +99,11 @@ function Base.show(io::IO, t::Pass) end if t.test_type === :test_throws # The correct type of exception was thrown - print(io, "\n Thrown: ", t.value isa String ? t.value : typeof(t.value)) + if t.message_only + print(io, "\n Message: ", t.value) + else + print(io, "\n Thrown: ", typeof(t.value)) + end elseif t.test_type === :test && t.data !== nothing # The test was an expression, so display the term-by-term # evaluated version as well @@ -118,12 +123,14 @@ struct Fail <: Result data::Union{Nothing, String} value::String source::LineNumberNode - function Fail(test_type::Symbol, orig_expr, data, value, source::LineNumberNode) + message_only::Bool + function Fail(test_type::Symbol, orig_expr, data, value, source::LineNumberNode, message_only::Bool=false) return new(test_type, string(orig_expr), data === nothing ? nothing : string(data), string(isa(data, Type) ? typeof(value) : value), - source) + source, + message_only) end end @@ -132,18 +139,24 @@ function Base.show(io::IO, t::Fail) print(io, " at ") printstyled(io, something(t.source.file, :none), ":", t.source.line, "\n"; bold=true, color=:default) print(io, " Expression: ", t.orig_expr) + value, data = t.value, t.data if t.test_type === :test_throws_wrong # An exception was thrown, but it was of the wrong type - print(io, "\n Expected: ", t.data) - print(io, "\n Thrown: ", t.value) + if t.message_only + print(io, "\n Expected: ", data) + print(io, "\n Message: ", value) + else + print(io, "\n Expected: ", data) + print(io, "\n Thrown: ", value) + end elseif t.test_type === :test_throws_nothing # An exception was expected, but no exception was thrown - print(io, "\n Expected: ", t.data) + print(io, "\n Expected: ", data) print(io, "\n No exception thrown") - elseif t.test_type === :test && t.data !== nothing + elseif t.test_type === :test && data !== nothing # The test was an expression, so display the term-by-term # evaluated version as well - print(io, "\n Evaluated: ", t.data) + print(io, "\n Evaluated: ", data) end end @@ -238,6 +251,7 @@ function Serialization.serialize(s::Serialization.AbstractSerializer, t::Pass) Serialization.serialize(s, t.data === nothing ? nothing : string(t.data)) Serialization.serialize(s, string(t.value)) Serialization.serialize(s, t.source === nothing ? nothing : t.source) + Serialization.serialize(s, t.message_only) nothing end @@ -657,6 +671,8 @@ end Tests that the expression `expr` throws `exception`. The exception may specify either a type, +a string, regular expression, or list of strings occurring in the displayed error message, +a matching function, or a value (which will be tested for equality by comparing fields). Note that `@test_throws` does not support a trailing keyword form. @@ -671,7 +687,18 @@ julia> @test_throws DimensionMismatch [1, 2, 3] + [1, 2] Test Passed Expression: [1, 2, 3] + [1, 2] Thrown: DimensionMismatch + +julia> @test_throws "Try sqrt(Complex" sqrt(-1) +Test Passed + Expression: sqrt(-1) + Message: "DomainError with -1.0:\\nsqrt will only return a complex result if called with a complex argument. Try sqrt(Complex(x))." ``` + +In the final example, instead of matching a single string it could alternatively have been performed with: + +- `["Try", "Complex"]` (a list of strings) +- `r"Try sqrt\\([Cc]omplex"` (a regular expression) +- `str -> occursin("complex", str)` (a matching function) """ macro test_throws(extype, ex) orig_ex = Expr(:inert, ex) @@ -697,6 +724,7 @@ function do_test_throws(result::ExecutionResult, orig_expr, extype) if isa(result, Threw) # Check that the right type of exception was thrown success = false + message_only = false exc = result.exception # NB: Throwing LoadError from macroexpands is deprecated, but in order to limit # the breakage in package tests we add extra logic here. @@ -712,7 +740,7 @@ function do_test_throws(result::ExecutionResult, orig_expr, extype) else isa(exc, extype) end - else + elseif isa(extype, Exception) || !isa(exc, Exception) if extype isa LoadError && !(exc isa LoadError) && typeof(extype.error) == typeof(exc) extype = extype.error # deprecated end @@ -725,11 +753,21 @@ function do_test_throws(result::ExecutionResult, orig_expr, extype) end end end + else + message_only = true + exc = sprint(showerror, exc) + success = contains_warn(exc, extype) + exc = repr(exc) + if isa(extype, AbstractString) + extype = repr(extype) + elseif isa(extype, Function) + extype = "< match function >" + end end if success - testres = Pass(:test_throws, orig_expr, extype, exc, result.source) + testres = Pass(:test_throws, orig_expr, extype, exc, result.source, message_only) else - testres = Fail(:test_throws_wrong, orig_expr, extype, exc, result.source) + testres = Fail(:test_throws_wrong, orig_expr, extype, exc, result.source, message_only) end else testres = Fail(:test_throws_nothing, orig_expr, extype, nothing, result.source) diff --git a/stdlib/Test/test/runtests.jl b/stdlib/Test/test/runtests.jl index 3c56ad8feba51b..d260c5840d6262 100644 --- a/stdlib/Test/test/runtests.jl +++ b/stdlib/Test/test/runtests.jl @@ -96,6 +96,16 @@ end "Thrown: ErrorException") @test endswith(sprint(show, @test_throws ErrorException("test") error("test")), "Thrown: ErrorException") + @test endswith(sprint(show, @test_throws "a test" error("a test")), + "Message: \"a test\"") + @test occursin("Message: \"DomainError", + sprint(show, @test_throws r"sqrt\([Cc]omplex" sqrt(-1))) + @test endswith(sprint(show, @test_throws str->occursin("a t", str) error("a test")), + "Message: \"a test\"") + @test endswith(sprint(show, @test_throws ["BoundsError", "access", "1-element", "at index [2]"] [1][2]), + "Message: \"BoundsError: attempt to access 1-element Vector{$Int} at index [2]\"") + @test_throws "\"" throw("\"") + @test_throws Returns(false) throw(Returns(false)) end # Test printing of Fail results include("nothrow_testset.jl") @@ -148,6 +158,11 @@ let fails = @testset NoThrowTestSet begin @test contains(str1, str2) # 22 - Fail - Type Comparison @test typeof(1) <: typeof("julia") + # 23 - 26 - Fail - wrong message + @test_throws "A test" error("a test") + @test_throws r"sqrt\([Cc]omplx" sqrt(-1) + @test_throws str->occursin("a T", str) error("a test") + @test_throws ["BoundsError", "acess", "1-element", "at index [2]"] [1][2] end for fail in fails @test fail isa Test.Fail @@ -262,6 +277,27 @@ let fails = @testset NoThrowTestSet begin @test occursin("Expression: typeof(1) <: typeof(\"julia\")", str) @test occursin("Evaluated: $(typeof(1)) <: $(typeof("julia"))", str) end + + let str = sprint(show, fails[23]) + @test occursin("Expected: \"A test\"", str) + @test occursin("Message: \"a test\"", str) + end + + let str = sprint(show, fails[24]) + @test occursin("Expected: r\"sqrt\\([Cc]omplx\"", str) + @test occursin(r"Message: .*Try sqrt\(Complex", str) + end + + let str = sprint(show, fails[25]) + @test occursin("Expected: < match function >", str) + @test occursin("Message: \"a test\"", str) + end + + let str = sprint(show, fails[26]) + @test occursin("Expected: [\"BoundsError\", \"acess\", \"1-element\", \"at index [2]\"]", str) + @test occursin(r"Message: \"BoundsError.* 1-element.*at index \[2\]", str) + end + end let errors = @testset NoThrowTestSet begin @@ -1202,4 +1238,4 @@ Test.finish(ts::PassInformationTestSet) = ts @test ts.results[2].data == ErrorException @test ts.results[2].value == ErrorException("Msg") @test ts.results[2].source == LineNumberNode(test_throws_line_number, @__FILE__) -end \ No newline at end of file +end From f2dcc44d20082d9e5a06c6abd6345c65b64984fb Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Fri, 13 Aug 2021 08:03:49 -0500 Subject: [PATCH 071/135] Remove unspecialized `reduce_empty` The fallback definitions of `reduce_empty` and `mapreduce_empty` are big targets for invalidation, and the benefit they bring is questionable. Instead of having a dedicated error path, instead we print a custom `MethodError` hint that is more informative than the current message. This fixes ~500 invalidations from DiffEqBase --- base/errorshow.jl | 6 ++++- base/reduce.jl | 38 ++++++++++++++++++++---------- stdlib/SparseArrays/test/sparse.jl | 6 +++-- test/abstractarray.jl | 3 ++- test/missing.jl | 12 +++++----- test/reduce.jl | 33 +++++++++++++++++--------- test/reducedim.jl | 11 +++++---- test/spawn.jl | 4 ++-- test/tuple.jl | 2 +- 9 files changed, 73 insertions(+), 42 deletions(-) diff --git a/base/errorshow.jl b/base/errorshow.jl index 6cd94cbed371a6..9d65c6ace9ebd9 100644 --- a/base/errorshow.jl +++ b/base/errorshow.jl @@ -226,6 +226,7 @@ function showerror(io::IO, ex::MethodError) return showerror_ambiguous(io, meth, f, arg_types) end arg_types_param::SimpleVector = arg_types.parameters + show_candidates = true print(io, "MethodError: ") ft = typeof(f) name = ft.name.mt.name @@ -242,6 +243,9 @@ function showerror(io::IO, ex::MethodError) if f === Base.convert && length(arg_types_param) == 2 && !is_arg_types f_is_function = true show_convert_error(io, ex, arg_types_param) + elseif f === mapreduce_empty || f === reduce_empty + print(io, "reducing over an empty collection is not allowed; consider supplying `init` to the reducer") + show_candidates = false elseif isempty(methods(f)) && isa(f, DataType) && isabstracttype(f) print(io, "no constructors have been defined for ", f) elseif isempty(methods(f)) && !isa(f, Function) && !isa(f, Type) @@ -314,7 +318,7 @@ function showerror(io::IO, ex::MethodError) end end Experimental.show_error_hints(io, ex, arg_types_param, kwargs) - try + show_candidates && try show_method_candidates(io, ex, kwargs) catch ex @error "Error showing method candidates, aborted" exception=ex,catch_backtrace() diff --git a/base/reduce.jl b/base/reduce.jl index aed7a546e144e2..59e6aeb117cfa6 100644 --- a/base/reduce.jl +++ b/base/reduce.jl @@ -299,6 +299,9 @@ pairwise_blocksize(::typeof(abs2), ::typeof(+)) = 4096 # handling empty arrays _empty_reduce_error() = throw(ArgumentError("reducing over an empty collection is not allowed")) +_empty_reduce_error(@nospecialize(f), @nospecialize(T::Type)) = throw(ArgumentError(""" + reducing with $f over an empty collection of element type $T is not allowed. + You may be able to prevent this error by supplying an `init` value to the reducer.""")) """ Base.reduce_empty(op, T) @@ -306,23 +309,32 @@ _empty_reduce_error() = throw(ArgumentError("reducing over an empty collection i The value to be returned when calling [`reduce`](@ref), [`foldl`](@ref) or [`foldr`](@ref) with reduction `op` over an empty array with element type of `T`. -If not defined, this will throw an `ArgumentError`. +This should only be defined in unambiguous cases; for example, + +```julia +Base.reduce_empty(::typeof(+), ::Type{T}) where T = zero(T) +``` + +is justified (the sum of zero elements is zero), whereas +`reduce_empty(::typeof(max), ::Type{Any})` is not (the maximum value of an empty collection +is generally ambiguous, and especially so when the element type is unknown). + +As an alternative, consider supplying an `init` value to the reducer. """ -reduce_empty(op, ::Type{T}) where {T} = _empty_reduce_error() -reduce_empty(::typeof(+), ::Type{Union{}}) = _empty_reduce_error() +reduce_empty(::typeof(+), ::Type{Union{}}) = _empty_reduce_error(+, Union{}) reduce_empty(::typeof(+), ::Type{T}) where {T} = zero(T) reduce_empty(::typeof(+), ::Type{Bool}) = zero(Int) -reduce_empty(::typeof(*), ::Type{Union{}}) = _empty_reduce_error() +reduce_empty(::typeof(*), ::Type{Union{}}) = _empty_reduce_error(*, Union{}) reduce_empty(::typeof(*), ::Type{T}) where {T} = one(T) reduce_empty(::typeof(*), ::Type{<:AbstractChar}) = "" reduce_empty(::typeof(&), ::Type{Bool}) = true reduce_empty(::typeof(|), ::Type{Bool}) = false -reduce_empty(::typeof(add_sum), ::Type{Union{}}) = _empty_reduce_error() +reduce_empty(::typeof(add_sum), ::Type{Union{}}) = _empty_reduce_error(add_sum, Union{}) reduce_empty(::typeof(add_sum), ::Type{T}) where {T} = reduce_empty(+, T) reduce_empty(::typeof(add_sum), ::Type{T}) where {T<:SmallSigned} = zero(Int) reduce_empty(::typeof(add_sum), ::Type{T}) where {T<:SmallUnsigned} = zero(UInt) -reduce_empty(::typeof(mul_prod), ::Type{Union{}}) = _empty_reduce_error() +reduce_empty(::typeof(mul_prod), ::Type{Union{}}) = _empty_reduce_error(mul_prod, Union{}) reduce_empty(::typeof(mul_prod), ::Type{T}) where {T} = reduce_empty(*, T) reduce_empty(::typeof(mul_prod), ::Type{T}) where {T<:SmallSigned} = one(Int) reduce_empty(::typeof(mul_prod), ::Type{T}) where {T<:SmallUnsigned} = one(UInt) @@ -337,11 +349,8 @@ reduce_empty(op::FlipArgs, ::Type{T}) where {T} = reduce_empty(op.f, T) The value to be returned when calling [`mapreduce`](@ref), [`mapfoldl`](@ref`) or [`mapfoldr`](@ref) with map `f` and reduction `op` over an empty array with element type -of `T`. - -If not defined, this will throw an `ArgumentError`. +of `T`. See [`Base.reduce_empty`](@ref) for more information. """ -mapreduce_empty(f, op, T) = _empty_reduce_error() mapreduce_empty(::typeof(identity), op, T) = reduce_empty(op, T) mapreduce_empty(::typeof(abs), op, T) = abs(reduce_empty(op, T)) mapreduce_empty(::typeof(abs2), op, T) = abs2(reduce_empty(op, T)) @@ -355,7 +364,10 @@ mapreduce_empty_iter(f, op, itr, ItrEltype) = @inline reduce_empty_iter(op, itr) = reduce_empty_iter(op, itr, IteratorEltype(itr)) @inline reduce_empty_iter(op, itr, ::HasEltype) = reduce_empty(op, eltype(itr)) -reduce_empty_iter(op, itr, ::EltypeUnknown) = _empty_reduce_error() +reduce_empty_iter(op, itr, ::EltypeUnknown) = throw(ArgumentError(""" + reducing over an empty collection of unknown element type is not allowed. + You may be able to prevent this error by supplying an `init` value to the reducer.""")) + # handling of single-element iterators """ @@ -726,7 +738,7 @@ julia> maximum([1,2,3]) 3 julia> maximum(()) -ERROR: ArgumentError: reducing over an empty collection is not allowed +ERROR: MethodError: reducing over an empty collection is not allowed; consider supplying `init` to the reducer Stacktrace: [...] @@ -758,7 +770,7 @@ julia> minimum([1,2,3]) 1 julia> minimum([]) -ERROR: ArgumentError: reducing over an empty collection is not allowed +ERROR: MethodError: reducing over an empty collection is not allowed; consider supplying `init` to the reducer Stacktrace: [...] diff --git a/stdlib/SparseArrays/test/sparse.jl b/stdlib/SparseArrays/test/sparse.jl index 221997a8f3384f..464dca3db15766 100644 --- a/stdlib/SparseArrays/test/sparse.jl +++ b/stdlib/SparseArrays/test/sparse.jl @@ -786,6 +786,8 @@ end end @testset "empty cases" begin + errchecker(str) = occursin("reducing over an empty collection is not allowed", str) || + occursin("collection slices must be non-empty", str) @test sum(sparse(Int[])) === 0 @test prod(sparse(Int[])) === 1 @test_throws ArgumentError minimum(sparse(Int[])) @@ -798,9 +800,9 @@ end @test isequal(f(spzeros(0, 1), dims=3), f(Matrix{Int}(I, 0, 1), dims=3)) end for f in (minimum, maximum, findmin, findmax) - @test_throws ArgumentError f(spzeros(0, 1), dims=1) + @test_throws errchecker f(spzeros(0, 1), dims=1) @test isequal(f(spzeros(0, 1), dims=2), f(Matrix{Int}(I, 0, 1), dims=2)) - @test_throws ArgumentError f(spzeros(0, 1), dims=(1, 2)) + @test_throws errchecker f(spzeros(0, 1), dims=(1, 2)) @test isequal(f(spzeros(0, 1), dims=3), f(Matrix{Int}(I, 0, 1), dims=3)) end end diff --git a/test/abstractarray.jl b/test/abstractarray.jl index c3537aac4e8874..32c367a7a50a84 100644 --- a/test/abstractarray.jl +++ b/test/abstractarray.jl @@ -1433,7 +1433,8 @@ using Base: typed_hvncat 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...) + @test_throws str->(occursin("`shape` argument must consist of positive integers", str) || + occursin("reducing over an empty collection is not allowed", str)) hvncat(((v1,), (v2,)), true, v3...) end end end diff --git a/test/missing.jl b/test/missing.jl index e1042f76fc7a71..0be8cb8ec9be41 100644 --- a/test/missing.jl +++ b/test/missing.jl @@ -465,10 +465,10 @@ end @test_throws BoundsError x[3, 1] @test findfirst(==(2), x) === nothing @test isempty(findall(==(2), x)) - @test_throws ArgumentError argmin(x) - @test_throws ArgumentError findmin(x) - @test_throws ArgumentError argmax(x) - @test_throws ArgumentError findmax(x) + @test_throws "reducing over an empty collection is not allowed" argmin(x) + @test_throws "reducing over an empty collection is not allowed" findmin(x) + @test_throws "reducing over an empty collection is not allowed" argmax(x) + @test_throws "reducing over an empty collection is not allowed" findmax(x) end end @@ -525,8 +525,8 @@ end for n in 0:3 itr = skipmissing(Vector{Union{Int,Missing}}(fill(missing, n))) @test sum(itr) == reduce(+, itr) == mapreduce(identity, +, itr) === 0 - @test_throws ArgumentError reduce(x -> x/2, itr) - @test_throws ArgumentError mapreduce(x -> x/2, +, itr) + @test_throws "reducing over an empty collection is not allowed" reduce(x -> x/2, itr) + @test_throws "reducing over an empty collection is not allowed" mapreduce(x -> x/2, +, itr) end # issue #35504 diff --git a/test/reduce.jl b/test/reduce.jl index 1e136af11b68a5..78ac22c13f366a 100644 --- a/test/reduce.jl +++ b/test/reduce.jl @@ -49,8 +49,8 @@ end @test reduce(max, [8 6 7 5 3 0 9]) == 9 @test reduce(+, 1:5; init=1000) == (1000 + 1 + 2 + 3 + 4 + 5) @test reduce(+, 1) == 1 -@test_throws ArgumentError reduce(*, ()) -@test_throws ArgumentError reduce(*, Union{}[]) +@test_throws "reducing with * over an empty collection of element type Union{} is not allowed" reduce(*, ()) +@test_throws "reducing with * over an empty collection of element type Union{} is not allowed" reduce(*, Union{}[]) # mapreduce @test mapreduce(-, +, [-10 -9 -3]) == ((10 + 9) + 3) @@ -87,8 +87,10 @@ end @test mapreduce(abs2, *, Float64[]) === 1.0 @test mapreduce(abs2, max, Float64[]) === 0.0 @test mapreduce(abs, max, Float64[]) === 0.0 -@test_throws ArgumentError mapreduce(abs2, &, Float64[]) -@test_throws ArgumentError mapreduce(abs2, |, Float64[]) +@test_throws ["reducing over an empty collection is not allowed", + "consider supplying `init`"] mapreduce(abs2, &, Float64[]) +@test_throws str -> !occursin("Closest candidates are", str) mapreduce(abs2, &, Float64[]) +@test_throws "reducing over an empty collection is not allowed" mapreduce(abs2, |, Float64[]) # mapreduce() type stability @test typeof(mapreduce(*, +, Int8[10])) === @@ -138,8 +140,9 @@ fz = float(z) @test sum(z) === 136 @test sum(fz) === 136.0 -@test_throws ArgumentError sum(Union{}[]) -@test_throws ArgumentError sum(sin, Int[]) +@test_throws "reducing with add_sum over an empty collection of element type Union{} is not allowed" sum(Union{}[]) +@test_throws ["reducing over an empty collection is not allowed", + "consider supplying `init`"] sum(sin, Int[]) @test sum(sin, 3) == sin(3.0) @test sum(sin, [3]) == sin(3.0) a = sum(sin, z) @@ -170,7 +173,7 @@ for f in (sum2, sum5, sum6, sum9, sum10) end for f in (sum3, sum4, sum7, sum8) @test sum(z) == f(z) - @test_throws ArgumentError f(Int[]) + @test_throws "reducing over an empty" f(Int[]) @test sum(Int[7]) == f(Int[7]) == 7 end @test typeof(sum(Int8[])) == typeof(sum(Int8[1])) == typeof(sum(Int8[1 7])) @@ -239,8 +242,8 @@ prod2(itr) = invoke(prod, Tuple{Any}, itr) # maximum & minimum & extrema -@test_throws ArgumentError maximum(Int[]) -@test_throws ArgumentError minimum(Int[]) +@test_throws "reducing over an empty" maximum(Int[]) +@test_throws "reducing over an empty" minimum(Int[]) @test maximum(Int[]; init=-1) == -1 @test minimum(Int[]; init=-1) == -1 @@ -594,14 +597,22 @@ end # issue #18695 test18695(r) = sum( t^2 for t in r ) @test @inferred(test18695([1.0,2.0,3.0,4.0])) == 30.0 -@test_throws ArgumentError test18695(Any[]) +@test_throws str -> ( occursin("reducing over an empty", str) && + occursin("consider supplying `init`", str) && + !occursin("or defining", str)) test18695(Any[]) + +# For Core.IntrinsicFunction +@test_throws str -> ( occursin("reducing over an empty", str) && + occursin("consider supplying `init`", str) && + !occursin("or defining", str)) reduce(Base.xor_int, Int[]) # issue #21107 @test foldr(-,2:2) == 2 # test neutral element not picked incorrectly for &, | @test @inferred(foldl(&, Int[1])) === 1 -@test_throws ArgumentError foldl(&, Int[]) +@test_throws ["reducing over an empty", + "consider supplying `init`"] foldl(&, Int[]) # prod on Chars @test prod(Char[]) == "" diff --git a/test/reducedim.jl b/test/reducedim.jl index 93287efc5eb1c0..f009a2384ca510 100644 --- a/test/reducedim.jl +++ b/test/reducedim.jl @@ -90,7 +90,7 @@ end # Combining dims and init A = Array{Int}(undef, 0, 3) -@test_throws ArgumentError maximum(A; dims=1) +@test_throws "reducing over an empty collection is not allowed" maximum(A; dims=1) @test maximum(A; dims=1, init=-1) == reshape([-1,-1,-1], 1, 3) # Test reduction along first dimension; this is special-cased for @@ -169,8 +169,9 @@ end A = Matrix{Int}(undef, 0,1) @test sum(A) === 0 @test prod(A) === 1 - @test_throws ArgumentError minimum(A) - @test_throws ArgumentError maximum(A) + @test_throws ["reducing over an empty", + "consider supplying `init`"] minimum(A) + @test_throws "consider supplying `init`" maximum(A) @test isequal(sum(A, dims=1), zeros(Int, 1, 1)) @test isequal(sum(A, dims=2), zeros(Int, 0, 1)) @@ -182,9 +183,9 @@ end @test isequal(prod(A, dims=3), fill(1, 0, 1)) for f in (minimum, maximum) - @test_throws ArgumentError f(A, dims=1) + @test_throws "reducing over an empty collection is not allowed" f(A, dims=1) @test isequal(f(A, dims=2), zeros(Int, 0, 1)) - @test_throws ArgumentError f(A, dims=(1, 2)) + @test_throws "reducing over an empty collection is not allowed" f(A, dims=(1, 2)) @test isequal(f(A, dims=3), zeros(Int, 0, 1)) end for f in (findmin, findmax) diff --git a/test/spawn.jl b/test/spawn.jl index 9ec7c6842bedbf..aa2281f667de80 100644 --- a/test/spawn.jl +++ b/test/spawn.jl @@ -579,8 +579,8 @@ end @test_throws ArgumentError run(Base.AndCmds(`$truecmd`, ``)) # tests for reducing over collection of Cmd -@test_throws ArgumentError reduce(&, Base.AbstractCmd[]) -@test_throws ArgumentError reduce(&, Base.Cmd[]) +@test_throws "reducing over an empty collection is not allowed" reduce(&, Base.AbstractCmd[]) +@test_throws "reducing over an empty collection is not allowed" reduce(&, Base.Cmd[]) @test reduce(&, [`$echocmd abc`, `$echocmd def`, `$echocmd hij`]) == `$echocmd abc` & `$echocmd def` & `$echocmd hij` # readlines(::Cmd), accidentally broken in #20203 diff --git a/test/tuple.jl b/test/tuple.jl index 9b44e421184d3e..bdfaae6bf10328 100644 --- a/test/tuple.jl +++ b/test/tuple.jl @@ -283,7 +283,7 @@ end @test mapfoldl(abs, =>, (-1,-2,-3,-4), init=-10) == ((((-10=>1)=>2)=>3)=>4) @test mapfoldl(abs, =>, (), init=-10) == -10 @test mapfoldl(abs, Pair{Any,Any}, (-30:-1...,)) == mapfoldl(abs, Pair{Any,Any}, [-30:-1...,]) - @test_throws ArgumentError mapfoldl(abs, =>, ()) + @test_throws "reducing over an empty collection" mapfoldl(abs, =>, ()) end @testset "filter" begin From eb2435f8681a15a248c730d8befdeb396b7e5be6 Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Fri, 13 Aug 2021 09:24:36 -0500 Subject: [PATCH 072/135] Allow specialization in show_convert_error `arg_types_param` is known to be a `Core.SimpleVector` --- base/errorshow.jl | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/base/errorshow.jl b/base/errorshow.jl index 9d65c6ace9ebd9..1ec7235b538a96 100644 --- a/base/errorshow.jl +++ b/base/errorshow.jl @@ -199,19 +199,20 @@ function print_with_compare(io::IO, @nospecialize(a), @nospecialize(b), color::S end end -function show_convert_error(io::IO, ex::MethodError, @nospecialize(arg_types_param)) +function show_convert_error(io::IO, ex::MethodError, arg_types_param) # See #13033 T = striptype(ex.args[1]) if T === nothing print(io, "First argument to `convert` must be a Type, got ", ex.args[1]) else - print_one_line = isa(T, DataType) && isa(arg_types_param[2], DataType) && T.name != arg_types_param[2].name + p2 = arg_types_param[2] + print_one_line = isa(T, DataType) && isa(p2, DataType) && T.name != p2.name printstyled(io, "Cannot `convert` an object of type ") print_one_line || printstyled(io, "\n ") - print_with_compare(io, arg_types_param[2], T, :light_green) + print_with_compare(io, p2, T, :light_green) printstyled(io, " to an object of type ") print_one_line || printstyled(io, "\n ") - print_with_compare(io, T, arg_types_param[2], :light_red) + print_with_compare(io, T, p2, :light_red) end end From be94c9c4f6472ede6befaa28be737985e16fc281 Mon Sep 17 00:00:00 2001 From: Arfon Smith Date: Wed, 18 Aug 2021 03:37:20 +0100 Subject: [PATCH 073/135] Updating CITATION.cff to use preferred-citation (#41907) --- CITATION.cff | 47 +++++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/CITATION.cff b/CITATION.cff index c052db4c304588..a25d61b69d849f 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -15,27 +15,26 @@ license: "MIT" doi: "10.1137/141000671" date-released: 2017-02-07 url: "https://julialang.org" -references: - - scope: "Cite this paper whenever you use Julia" - type: article - title: "Julia: A fresh approach to numerical computing" - authors: - - family-names: "Bezanson" - given-names: "Jeff" - - family-names: "Edelman" - given-names: "Alan" - - family-names: "Karpinski" - given-names: "Stefan" - - family-names: "Shah" - given-names: "Viral B." - doi: "10.1137/141000671" - journal: "SIAM Review" - volume: 59 - number: 1 - pages: 33 - start: 65 - end: 98 - year: 2017 - url: "https://dx.doi.org/10.1137/141000671" - publisher: - - name: "SIAM" +preferred-citation: + authors: + - family-names: "Bezanson" + given-names: "Jeff" + - family-names: "Edelman" + given-names: "Alan" + - family-names: "Karpinski" + given-names: "Stefan" + - family-names: "Shah" + given-names: "Viral B." + doi: "10.1137/141000671" + journal: "SIAM Review" + month: 9 + start: 65 + end: 98 + pages: 33 + title: "Julia: A fresh approach to numerical computing" + type: article + volume: 59 + issue: 1 + year: 2017 + publisher: + - name: "SIAM" From 232ee11fe99b89a1f72e462692cb4245a186b9ce Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Wed, 18 Aug 2021 03:19:23 -0500 Subject: [PATCH 074/135] Fix ~370 invalidations from Expr(:ncat, ...) pretty-printing (#41877) These get invalidated by loading Static.jl, specifically the method ``` Base.convert(::Type{T}, ::StaticInt{N}) where {T<:Number,N} = convert(T, N) ``` --- base/show.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/show.jl b/base/show.jl index 4fa8ba2e2cded2..40fe1ec7d64f04 100644 --- a/base/show.jl +++ b/base/show.jl @@ -1832,7 +1832,7 @@ function show_unquoted(io::IO, ex::Expr, indent::Int, prec::Int, quote_level::In elseif head === :hcat || head === :row sep = " " elseif head === :ncat || head === :nrow - sep = ";"^args[1] * " " + sep = ";"^args[1]::Int * " " args = args[2:end] nargs = nargs - 1 else From 7a6336d41a4064c0bf3649fb3b1a2ec3531a7dd8 Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Wed, 18 Aug 2021 03:25:18 -0500 Subject: [PATCH 075/135] Fix ~50 invalidations stemming from `modules_to_be_loaded` (#41878) ChainRulesCore defines `==(a, b::AbstractThunk)` and its converse, and these end up invaliding parts of the REPL (including `eval_user_input`) via inference failures in `modules_to_be_loaded`. Co-authored by: Jameson Nash --- stdlib/REPL/src/REPL.jl | 14 ++++++++------ stdlib/REPL/test/repl.jl | 2 -- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/stdlib/REPL/src/REPL.jl b/stdlib/REPL/src/REPL.jl index d2054990ceb81f..9a9114aed9e3da 100644 --- a/stdlib/REPL/src/REPL.jl +++ b/stdlib/REPL/src/REPL.jl @@ -168,6 +168,7 @@ function eval_user_input(@nospecialize(ast), backend::REPLBackend) end function check_for_missing_packages_and_run_hooks(ast) + isa(ast, Expr) || return mods = modules_to_be_loaded(ast) filter!(mod -> isnothing(Base.identify_package(String(mod))), mods) # keep missing modules if !isempty(mods) @@ -177,16 +178,18 @@ function check_for_missing_packages_and_run_hooks(ast) end end -function modules_to_be_loaded(ast, mods = Symbol[]) +function modules_to_be_loaded(ast::Expr, mods::Vector{Symbol} = Symbol[]) ast.head == :quote && return mods # don't search if it's not going to be run during this eval if ast.head in [:using, :import] for arg in ast.args - if first(arg.args) isa Symbol # i.e. `Foo` - if first(arg.args) != :. # don't include local imports - push!(mods, first(arg.args)) + arg = arg::Expr + arg1 = first(arg.args) + if arg1 isa Symbol # i.e. `Foo` + if arg1 != :. # don't include local imports + push!(mods, arg1) end else # i.e. `Foo: bar` - push!(mods, first(first(arg.args).args)) + push!(mods, first((arg1::Expr).args)) end end end @@ -196,7 +199,6 @@ function modules_to_be_loaded(ast, mods = Symbol[]) filter!(mod -> !in(String(mod), ["Base", "Main", "Core"]), mods) # Exclude special non-package modules return mods end -modules_to_be_loaded(::Nothing) = Symbol[] # comments are parsed as nothing """ start_repl_backend(repl_channel::Channel, response_channel::Channel) diff --git a/stdlib/REPL/test/repl.jl b/stdlib/REPL/test/repl.jl index 8d67be4b773d2e..6724eb5e13ac3c 100644 --- a/stdlib/REPL/test/repl.jl +++ b/stdlib/REPL/test/repl.jl @@ -1360,8 +1360,6 @@ end mods = REPL.modules_to_be_loaded(Base.parse_input_line("ex = :(using Foo)")) @test isempty(mods) - mods = REPL.modules_to_be_loaded(Base.parse_input_line("# comment")) - @test isempty(mods) mods = REPL.modules_to_be_loaded(Base.parse_input_line("Foo")) @test isempty(mods) end From 746734ce293b8e7e49206736dea39849b065aeb3 Mon Sep 17 00:00:00 2001 From: Rohit Singh Rathaur <42641738+RohitRathore1@users.noreply.github.com> Date: Wed, 18 Aug 2021 21:05:39 +0530 Subject: [PATCH 076/135] BigFloat: fix inconsistency in allowed precision (#40872) Fixes #40538 --- base/mpfr.jl | 4 ++-- test/mpfr.jl | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/base/mpfr.jl b/base/mpfr.jl index a53852626f42ce..0ffb0f50b1034c 100644 --- a/base/mpfr.jl +++ b/base/mpfr.jl @@ -815,8 +815,8 @@ Set the precision (in bits) to be used for `T` arithmetic. setting. """ function setprecision(::Type{BigFloat}, precision::Integer) - if precision < 2 - throw(DomainError(precision, "`precision` cannot be less than 2.")) + if precision < 1 + throw(DomainError(precision, "`precision` cannot be less than 1.")) end DEFAULT_PRECISION[] = precision return precision diff --git a/test/mpfr.jl b/test/mpfr.jl index 0b6ff30e372dc8..cbaa69761a4e35 100644 --- a/test/mpfr.jl +++ b/test/mpfr.jl @@ -475,7 +475,8 @@ end @test precision(z) == 240 x = BigFloat(12) @test precision(x) == old_precision - @test_throws DomainError setprecision(1) + @test precision(setprecision(1) do; BigFloat(23); end) == 1 # minimum-precision + @test_throws DomainError setprecision(0) @test_throws DomainError BigFloat(1, precision = 0) @test_throws DomainError BigFloat(big(1.1), precision = 0) @test_throws DomainError BigFloat(2.5, precision = -900) From 2cb8e17bd9ae532e2172d5e841ed097ed079fc68 Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Wed, 18 Aug 2021 10:36:13 -0500 Subject: [PATCH 077/135] Attribution for "insert_backedges" invalidations (#41913) Invalidations can be immediate (when an existing MethodInstance gets invalidated by a new method definition) or delayed. The latter occurs during deserialization: when a package was built, a particular call dispatches to Method 1, but when loaded (due to different loading orders and dependencies) it should instead dispatch to Method 2. These delayed invalidations are not particularly common, and perhaps because of this SnoopCompile has never supported them well: they have merely been dumped to the console during `invalidation_tree` construction. However, in larger software stacks they seem to become more common, and can dramatically affect precompilation success. This simple PR identifies "causes" for such delayed invalidations, allowing SnoopCompile to determine (in most cases) the particular definition or deletion that triggered the change in dispatch. --- src/dump.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/dump.c b/src/dump.c index 49fa6efa431cd9..8c9d68f51834be 100644 --- a/src/dump.c +++ b/src/dump.c @@ -1963,6 +1963,8 @@ static void jl_verify_edges(jl_array_t *targets, jl_array_t **pvalids) size_t i, l = jl_array_len(targets) / 2; jl_array_t *valids = jl_alloc_array_1d(jl_array_uint8_type, l); memset(jl_array_data(valids), 1, l); + jl_value_t *loctag = NULL; + JL_GC_PUSH1(&loctag); *pvalids = valids; for (i = 0; i < l; i++) { jl_value_t *callee = jl_array_ptr_ref(targets, i * 2); @@ -2004,7 +2006,13 @@ static void jl_verify_edges(jl_array_t *targets, jl_array_t **pvalids) } } jl_array_uint8_set(valids, i, valid); + if (!valid && _jl_debug_method_invalidation) { + jl_array_ptr_1d_push(_jl_debug_method_invalidation, (jl_value_t*)callee); + loctag = jl_cstr_to_string("insert_backedges_callee"); + jl_array_ptr_1d_push(_jl_debug_method_invalidation, loctag); + } } + JL_GC_POP(); } static void jl_insert_backedges(jl_array_t *list, jl_array_t *targets) From f73858072c18f09c65490408e7102816570b5101 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Thu, 19 Aug 2021 03:51:12 +0900 Subject: [PATCH 078/135] use explicit keyword arguments for `specialize_method` (#41920) It would be a bit easier to reason about the configurations. --- base/compiler/abstractinterpretation.jl | 4 ++-- base/compiler/ssair/inlining.jl | 6 +++--- base/compiler/utilities.jl | 8 ++++---- test/compiler/validation.jl | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index 296a30cdb2e0ff..efcebf8c1408e7 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -584,7 +584,7 @@ function maybe_get_const_prop_profitable(interp::AbstractInterpreter, result::Me end end force |= allconst - mi = specialize_method(match, !force) + mi = specialize_method(match; preexisting=!force) if mi === nothing add_remark!(interp, sv, "[constprop] Failed to specialize") return nothing @@ -983,7 +983,7 @@ end function is_method_pure(method::Method, @nospecialize(sig), sparams::SimpleVector) if isdefined(method, :generator) method.generator.expand_early || return false - mi = specialize_method(method, sig, sparams, false) + mi = specialize_method(method, sig, sparams) isa(mi, MethodInstance) || return false staged = get_staged(mi) (staged isa CodeInfo && (staged::CodeInfo).pure) || return false diff --git a/base/compiler/ssair/inlining.jl b/base/compiler/ssair/inlining.jl index 5bbf576d9f5364..7e7baff1367415 100644 --- a/base/compiler/ssair/inlining.jl +++ b/base/compiler/ssair/inlining.jl @@ -708,13 +708,13 @@ function singleton_type(@nospecialize(ft)) end function compileable_specialization(et::Union{EdgeTracker, Nothing}, match::MethodMatch) - mi = specialize_method(match, false, true) + mi = specialize_method(match; compilesig=true) mi !== nothing && et !== nothing && push!(et, mi::MethodInstance) return mi end function compileable_specialization(et::Union{EdgeTracker, Nothing}, (; linfo)::InferenceResult) - mi = specialize_method(linfo.def::Method, linfo.specTypes, linfo.sparam_vals, false, true) + mi = specialize_method(linfo.def::Method, linfo.specTypes, linfo.sparam_vals; compilesig=true) mi !== nothing && et !== nothing && push!(et, mi::MethodInstance) return mi end @@ -809,7 +809,7 @@ function analyze_method!(match::MethodMatch, atypes::Vector{Any}, end # See if there exists a specialization for this method signature - mi = specialize_method(match, true) # Union{Nothing, MethodInstance} + mi = specialize_method(match; preexisting=true) # Union{Nothing, MethodInstance} if !isa(mi, MethodInstance) return compileable_specialization(et, match) end diff --git a/base/compiler/utilities.jl b/base/compiler/utilities.jl index ed31e382d11525..5d4d52172a300a 100644 --- a/base/compiler/utilities.jl +++ b/base/compiler/utilities.jl @@ -176,7 +176,7 @@ function normalize_typevars(method::Method, @nospecialize(atypes), sparams::Simp end # get a handle to the unique specialization object representing a particular instantiation of a call -function specialize_method(method::Method, @nospecialize(atypes), sparams::SimpleVector, preexisting::Bool=false, compilesig::Bool=false) +function specialize_method(method::Method, @nospecialize(atypes), sparams::SimpleVector; preexisting::Bool=false, compilesig::Bool=false) if isa(atypes, UnionAll) atypes, sparams = normalize_typevars(method, atypes, sparams) end @@ -193,14 +193,14 @@ function specialize_method(method::Method, @nospecialize(atypes), sparams::Simpl return ccall(:jl_specializations_get_linfo, Ref{MethodInstance}, (Any, Any, Any), method, atypes, sparams) end -function specialize_method(match::MethodMatch, preexisting::Bool=false, compilesig::Bool=false) - return specialize_method(match.method, match.spec_types, match.sparams, preexisting, compilesig) +function specialize_method(match::MethodMatch; kwargs...) + return specialize_method(match.method, match.spec_types, match.sparams; kwargs...) end # This function is used for computing alternate limit heuristics function method_for_inference_heuristics(method::Method, @nospecialize(sig), sparams::SimpleVector) if isdefined(method, :generator) && method.generator.expand_early && may_invoke_generator(method, sig, sparams) - method_instance = specialize_method(method, sig, sparams, false) + method_instance = specialize_method(method, sig, sparams) if isa(method_instance, MethodInstance) cinfo = get_staged(method_instance) if isa(cinfo, CodeInfo) diff --git a/test/compiler/validation.jl b/test/compiler/validation.jl index d07007069b5c8b..3863d3b11351fb 100644 --- a/test/compiler/validation.jl +++ b/test/compiler/validation.jl @@ -21,7 +21,7 @@ end msig = Tuple{typeof(f22938),Int,Int,Int,Int} world = typemax(UInt) match = Base._methods_by_ftype(msig, -1, world)[] -mi = Core.Compiler.specialize_method(match, false) +mi = Core.Compiler.specialize_method(match) c0 = Core.Compiler.retrieve_code_info(mi) @test isempty(Core.Compiler.validate_code(mi)) From 5a39be832268d5263c7103f68309781a1b98901f Mon Sep 17 00:00:00 2001 From: Simeon Schaub Date: Wed, 18 Aug 2021 21:13:40 +0200 Subject: [PATCH 079/135] add hook for manually adding coverage data (#41904) This would allow packages like JuliaInterpreter to properly report coverage data. --- src/codegen.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/codegen.cpp b/src/codegen.cpp index d05080ee4216e9..744d29629b0cae 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -1897,6 +1897,16 @@ static void coverageAllocLine(StringRef filename, int line) allocLine(coverageData[filename], line); } +extern "C" JL_DLLEXPORT void jl_coverage_visit_line(const char* filename_, size_t len_filename, int line) +{ + StringRef filename = StringRef(filename_, len_filename); + if (imaging_mode || filename == "" || filename == "none" || filename == "no file" || filename == "" || line < 0) + return; + std::vector &vec = coverageData[filename]; + uint64_t *ptr = allocLine(vec, line); + (*ptr)++; +} + // Memory allocation log (malloc_log) static logdata_t mallocData; From 6e0bac9421aa777c42d5b16621d85c022cb703cd Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Wed, 18 Aug 2021 16:48:32 -0400 Subject: [PATCH 080/135] Add check for buffer size of Profile.init on 32-bit systems, and fix bug (#41906) * fix bug multiplying by nthreads twice * limit buffer to 512MB on 32-bit. Add info to error --- stdlib/Profile/src/Profile.jl | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/stdlib/Profile/src/Profile.jl b/stdlib/Profile/src/Profile.jl index fbb9a820e76913..49f5020d277c42 100644 --- a/stdlib/Profile/src/Profile.jl +++ b/stdlib/Profile/src/Profile.jl @@ -55,17 +55,26 @@ function init(; n::Union{Nothing,Integer} = nothing, delay::Union{Nothing,Real} if n === nothing && delay === nothing return Int(n_cur), delay_cur end - nthreads = Sys.iswindows() ? 1 : Threads.nthreads() # windows only profiles the main thread - nnew = (n === nothing) ? n_cur : n * nthreads + nnew = (n === nothing) ? n_cur : n delaynew = (delay === nothing) ? delay_cur : delay init(nnew, delaynew) end function init(n::Integer, delay::Real) nthreads = Sys.iswindows() ? 1 : Threads.nthreads() # windows only profiles the main thread - status = ccall(:jl_profile_init, Cint, (Csize_t, UInt64), n * nthreads, round(UInt64,10^9*delay)) + sample_size_bytes = sizeof(Ptr) # == Sys.WORD_SIZE / 8 + buffer_samples = n * nthreads + buffer_size_bytes = buffer_samples * sample_size_bytes + if buffer_size_bytes > 2^29 && Sys.WORD_SIZE == 32 + buffer_size_bytes_per_thread = floor(Int, 2^29 / nthreads) + buffer_samples_per_thread = floor(Int, buffer_size_bytes_per_thread / sample_size_bytes) + buffer_samples = buffer_samples_per_thread * nthreads + buffer_size_bytes = buffer_samples * sample_size_bytes + @warn "Requested profile buffer limited to 512MB (n = $buffer_samples_per_thread per thread) given that this system is 32-bit" + end + status = ccall(:jl_profile_init, Cint, (Csize_t, UInt64), buffer_samples, round(UInt64,10^9*delay)) if status == -1 - error("could not allocate space for ", n, " instruction pointers per thread being profiled ($nthreads threads)") + error("could not allocate space for ", n, " instruction pointers per thread being profiled ($nthreads threads, $(Base.format_bytes(buffer_size_bytes)) total)") end end From 0f24ba2cb6142ad9e831589317ca602743e1d800 Mon Sep 17 00:00:00 2001 From: Simeon Schaub Date: Wed, 18 Aug 2021 22:49:17 +0200 Subject: [PATCH 081/135] fix module redefinition warning when running tests (#41905) --- test/compiler/inference.jl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/compiler/inference.jl b/test/compiler/inference.jl index 6bd8df57e8a8ab..1e61cc9e440946 100644 --- a/test/compiler/inference.jl +++ b/test/compiler/inference.jl @@ -3005,14 +3005,14 @@ end # Some very limited testing of timing the type inference (#37749). @testset "Core.Compiler.Timings" begin # Functions that call each other - @eval module M + @eval module M1 i(x) = x+5 i2(x) = x+2 h(a::Array) = i2(a[1]::Integer) + i(a[1]::Integer) + 2 g(y::Integer, x) = h(Any[y]) + Int(x) end timing1 = time_inference() do - @eval M.g(2, 3.0) + @eval M1.g(2, 3.0) end @test occursin(r"Core.Compiler.Timings.Timing\(InferenceFrameInfo for Core.Compiler.Timings.ROOT\(\)\) with \d+ children", sprint(show, timing1)) # The last two functions to be inferred should be `i` and `i2`, inferred at runtime with @@ -3024,11 +3024,11 @@ end @test isa(stacktrace(timing1.children[1].bt), Vector{Base.StackTraces.StackFrame}) # Test that inference has cached some of the Method Instances timing2 = time_inference() do - @eval M.g(2, 3.0) + @eval M1.g(2, 3.0) end @test length(flatten_times(timing2)) < length(flatten_times(timing1)) # Printing of InferenceFrameInfo for mi.def isa Module - @eval module M + @eval module M2 i(x) = x+5 i2(x) = x+2 h(a::Array) = i2(a[1]::Integer) + i(a[1]::Integer) + 2 @@ -3038,7 +3038,7 @@ end timingmod = time_inference() do @eval @testset "Outer" begin @testset "Inner" begin - for i = 1:2 M.g(2, 3.0) end + for i = 1:2 M2.g(2, 3.0) end end end end From 5e1670e7865b5ea73aa3a9c3dd42c8596c04aea1 Mon Sep 17 00:00:00 2001 From: Alex Arslan Date: Wed, 18 Aug 2021 13:50:06 -0700 Subject: [PATCH 082/135] Update BinaryBuilder libuv to 2.0.1+4 (#41900) The FreeBSD binaries for this build are built with FreeBSD 12 rather than FreeBSD 11, which will work around issue #34627. --- deps/checksums/libuv | 64 +++++++++++++++++------------------ stdlib/LibUV_jll/Project.toml | 2 +- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/deps/checksums/libuv b/deps/checksums/libuv index f3ecef65865474..1dddd23bcd992c 100644 --- a/deps/checksums/libuv +++ b/deps/checksums/libuv @@ -1,34 +1,34 @@ -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.v2.0.1+4.aarch64-apple-darwin.tar.gz/md5/c44261bfb4a254100af5085624e9805c +LibUV.v2.0.1+4.aarch64-apple-darwin.tar.gz/sha512/f94b74fcd6a39c903f05efdd626cbe6af9016099f37cfbe0da50c0dce962a7998f884a38a586b14a9b5e7a01b96f653e5e204afbcf2c22188834394de3b3e607 +LibUV.v2.0.1+4.aarch64-linux-gnu.tar.gz/md5/5cf0c759aacd96784a81b464240901ae +LibUV.v2.0.1+4.aarch64-linux-gnu.tar.gz/sha512/b8488345516cf424bcf4b4637799cbfcf6019b109dd6104784d09381a85d4f145c02d0e0ad3a3a3679b68b7d5a5ef0a9d63cbed62734272c80e8e3927eb047f5 +LibUV.v2.0.1+4.aarch64-linux-musl.tar.gz/md5/1c3ef838685ec4b32a68ee260cd9dfba +LibUV.v2.0.1+4.aarch64-linux-musl.tar.gz/sha512/f2560edceeb680ad46a3f4146a0d22f28a6727e892520f9599f0d5a105b0d7776dadf688b48e773f7e5b2d4204d3f56bd0f8f23d09c6ac5b4d6cd85c05a20fe5 +LibUV.v2.0.1+4.armv6l-linux-gnueabihf.tar.gz/md5/bc7fa34f167fa6ed945ef2f29807e910 +LibUV.v2.0.1+4.armv6l-linux-gnueabihf.tar.gz/sha512/124646ac504e8f995bccfcac0b8ae5ef524016f1cc2f2e58e058b23624193c52ab7f554ea4ffcb3046422e638cb2422442a8fcfb9e8b828d173f1f97d5ade910 +LibUV.v2.0.1+4.armv6l-linux-musleabihf.tar.gz/md5/c123949e81d4e49c8e1a4a63327c2ccf +LibUV.v2.0.1+4.armv6l-linux-musleabihf.tar.gz/sha512/b04aa8e293abcabf125e63d11efd56215d3605e1709b2635a7325d84b5e4de7174fb69695bde3c1e042309333f7ad80f8782bc8a9576efdbfe8cac62dcbba7bc +LibUV.v2.0.1+4.armv7l-linux-gnueabihf.tar.gz/md5/eb031d1135a79615381f3010b85e4a02 +LibUV.v2.0.1+4.armv7l-linux-gnueabihf.tar.gz/sha512/13383beb19cf6fa6601d02fd7c193f27877ccc63acefd935edd2ff7c13d4b8d8b900b5571da19fe418e007e3ade4c49c1f64a971326abb50aca5dec60c10a4b6 +LibUV.v2.0.1+4.armv7l-linux-musleabihf.tar.gz/md5/09ce6bb24ca286f92675349d583c03db +LibUV.v2.0.1+4.armv7l-linux-musleabihf.tar.gz/sha512/a71f58f61e7bbd479bb66c560804b99b0e4218df0e9b4b325b254cd58d8ab8600eca35a8b9b5e54f57099834ec22e36a1a11fb923b150305c7561242b7e62030 +LibUV.v2.0.1+4.i686-linux-gnu.tar.gz/md5/1efc848d7961a677cdeb0acec37d826b +LibUV.v2.0.1+4.i686-linux-gnu.tar.gz/sha512/8855729060b7e59a5a34ff2aea209d4af84657d7b801e736fc374d49d338e1bc87796e3346eeac7340f3e8e1f8037bf420144f04d81b93d3017fb5a32eece43a +LibUV.v2.0.1+4.i686-linux-musl.tar.gz/md5/71bde27fb51e9c7ccfe1c7eab34afbb4 +LibUV.v2.0.1+4.i686-linux-musl.tar.gz/sha512/588616fd1ff342e8070def2121fa2dd6be349e9ff1d19653d2414f0c713ba02d50a89aa7cdddeb19e6864654690c870164238204767990f09b277ddf788c9935 +LibUV.v2.0.1+4.i686-w64-mingw32.tar.gz/md5/090d2e845fcef61c3ef019fdbf7877df +LibUV.v2.0.1+4.i686-w64-mingw32.tar.gz/sha512/aaea203d285ee490803852d27fc628763358680e05373208385f85ca33d14bc09baf63cf243fd45788ef68b415858e5d919178574322cfc9e4a42774227ba8ab +LibUV.v2.0.1+4.powerpc64le-linux-gnu.tar.gz/md5/b69fd18d09ab59e3b139963b3988321e +LibUV.v2.0.1+4.powerpc64le-linux-gnu.tar.gz/sha512/e257c2c86af1c7a7ab76cd08faabf7e74ef9fa462e0f8f3df346d11a249157b4b47130fad44b47317d358bf74233bb9b854c57a9b76c29c0e05f15f9322b8b53 +LibUV.v2.0.1+4.x86_64-apple-darwin.tar.gz/md5/4242ead21755564805144cf2712e3d55 +LibUV.v2.0.1+4.x86_64-apple-darwin.tar.gz/sha512/f7448587af8186c5eb59f81cca7f48f840578440762b22a7a122e8243509bb9e2c541e337c1f2d1e94599cce1a928ec6b6c14e219e412bed21d82a68416caece +LibUV.v2.0.1+4.x86_64-linux-gnu.tar.gz/md5/46155e2617a76e3910f379c33127a31b +LibUV.v2.0.1+4.x86_64-linux-gnu.tar.gz/sha512/fa94f0dea120ff5381e7803672dd588ef69990d488bc7124c662a55ab52805b874b0913fb5c2b623ccf22ff0d1065229c3a06f44669a758b8186464118902b35 +LibUV.v2.0.1+4.x86_64-linux-musl.tar.gz/md5/921637f115807c2f0b86d6a5c1949789 +LibUV.v2.0.1+4.x86_64-linux-musl.tar.gz/sha512/95ee29a34d919dae348fea2ca81d7549be8210143936987ea68f28271331983e4358aaba884edc5e1fd16eef8e9d35770f6b113d3f1db412a3a829d381b9df42 +LibUV.v2.0.1+4.x86_64-unknown-freebsd.tar.gz/md5/f4e733fa82a5a34da86a8e9d143596c1 +LibUV.v2.0.1+4.x86_64-unknown-freebsd.tar.gz/sha512/f6e390126d2e75c2dd32da40db48905c48134437e52634101d10ade67b7426101324ccf652bb4c4cc29272c5b641d5543e673bac7c6ec1c31f8d7e77f61c09c0 +LibUV.v2.0.1+4.x86_64-w64-mingw32.tar.gz/md5/1c8e63632fb40fa97805efde91de764d +LibUV.v2.0.1+4.x86_64-w64-mingw32.tar.gz/sha512/2c64ac559beccbee8ce62dc0ce0277d8eaca5e46c13585bf10d2a79811bf4f5dcac30d49b2b6a02472c72857a859be021e4e7114f30e560f97c4e3979486dc7c libuv-c6869fba163a1e04af64ede438a8fd0191e75e9e.tar.gz/md5/b60fc7b00bdfafcbbc66317858882058 libuv-c6869fba163a1e04af64ede438a8fd0191e75e9e.tar.gz/sha512/197b386af51eb4456ce65e2951e033731e1194fca8bed08755a78360ebb3431ab4d8d69a75279e7995d2e4197133d613892e5b9b5d6411bffa692df35542420f diff --git a/stdlib/LibUV_jll/Project.toml b/stdlib/LibUV_jll/Project.toml index 6a5e2c8ca891be..6950964b888a0a 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+3" +version = "2.0.1+4" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" From 2e82c0dc19144fc3cd676f82db9a96d4ba1fa571 Mon Sep 17 00:00:00 2001 From: Daniel Karrasch Date: Wed, 18 Aug 2021 23:06:58 +0200 Subject: [PATCH 083/135] Avoid potential ambiguities for `[h/v/hv]cat` in packages (#41511) --- stdlib/LinearAlgebra/src/uniformscaling.jl | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/stdlib/LinearAlgebra/src/uniformscaling.jl b/stdlib/LinearAlgebra/src/uniformscaling.jl index bbcade43c5569d..58e2be00be8392 100644 --- a/stdlib/LinearAlgebra/src/uniformscaling.jl +++ b/stdlib/LinearAlgebra/src/uniformscaling.jl @@ -404,9 +404,11 @@ promote_to_arrays(n,k, ::Type{T}, A, B, Cs...) where {T} = (promote_to_arrays_(n[k], T, A), promote_to_arrays_(n[k+1], T, B), promote_to_arrays(n,k+2, T, Cs...)...) promote_to_array_type(A::Tuple{Vararg{Union{AbstractVecOrMat,UniformScaling,Number}}}) = Matrix -for (f,dim,name) in ((:hcat,1,"rows"), (:vcat,2,"cols")) +for (f, _f, dim, name) in ((:hcat, :_hcat, 1, "rows"), (:vcat, :_vcat, 2, "cols")) @eval begin - function $f(A::Union{AbstractVecOrMat,UniformScaling,Number}...) + @inline $f(A::Union{AbstractVecOrMat,UniformScaling}...) = $_f(A...) + @inline $f(A::Union{AbstractVecOrMat,UniformScaling,Number}...) = $_f(A...) + function $_f(A::Union{AbstractVecOrMat,UniformScaling,Number}...) n = -1 for a in A if !isa(a, UniformScaling) @@ -424,8 +426,9 @@ for (f,dim,name) in ((:hcat,1,"rows"), (:vcat,2,"cols")) end end - -function hvcat(rows::Tuple{Vararg{Int}}, A::Union{AbstractVecOrMat,UniformScaling,Number}...) +hvcat(rows::Tuple{Vararg{Int}}, A::Union{AbstractVecOrMat,UniformScaling}...) = _hvcat(rows, A...) +hvcat(rows::Tuple{Vararg{Int}}, A::Union{AbstractVecOrMat,UniformScaling,Number}...) = _hvcat(rows, A...) +function _hvcat(rows::Tuple{Vararg{Int}}, A::Union{AbstractVecOrMat,UniformScaling,Number}...) require_one_based_indexing(A...) nr = length(rows) sum(rows) == length(A) || throw(ArgumentError("mismatch between row sizes and number of arguments")) From 0771939d184e1580492939b8117af82d4a9add45 Mon Sep 17 00:00:00 2001 From: Mark Kittisopikul Date: Wed, 18 Aug 2021 17:07:49 -0400 Subject: [PATCH 084/135] Allow AbstractUnitRange for string getindex (#41807) --- base/strings/string.jl | 2 +- base/strings/substring.jl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/base/strings/string.jl b/base/strings/string.jl index e3a9cd56df2019..c818e2e1844fbe 100644 --- a/base/strings/string.jl +++ b/base/strings/string.jl @@ -252,7 +252,7 @@ function getindex_continued(s::String, i::Int, u::UInt32) return reinterpret(Char, u) end -getindex(s::String, r::UnitRange{<:Integer}) = s[Int(first(r)):Int(last(r))] +getindex(s::String, r::AbstractUnitRange{<:Integer}) = s[Int(first(r)):Int(last(r))] @inline function getindex(s::String, r::UnitRange{Int}) isempty(r) && return "" diff --git a/base/strings/substring.jl b/base/strings/substring.jl index 3e99cc7477446d..0da09f36be9310 100644 --- a/base/strings/substring.jl +++ b/base/strings/substring.jl @@ -252,4 +252,4 @@ function filter(f, s::Union{String, SubString{String}}) return String(out) end -getindex(s::AbstractString, r::UnitRange{<:Integer}) = SubString(s, r) +getindex(s::AbstractString, r::AbstractUnitRange{<:Integer}) = SubString(s, r) From 543386de12df43ef98bc867fbd9d85c0b7dee5f8 Mon Sep 17 00:00:00 2001 From: Thomas Christensen Date: Wed, 18 Aug 2021 17:08:04 -0400 Subject: [PATCH 085/135] force type stability of `_invoked_shouldlog` & friends for non-concrete loggers (#41863) --- base/logging.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/base/logging.jl b/base/logging.jl index 8177d1eddff843..712fe19c23699a 100644 --- a/base/logging.jl +++ b/base/logging.jl @@ -79,15 +79,15 @@ function _invoked_shouldlog(logger, level, _module, group, id) shouldlog, Tuple{typeof(logger), typeof(level), typeof(_module), typeof(group), typeof(id)}, logger, level, _module, group, id - ) + )::Bool end function _invoked_min_enabled_level(@nospecialize(logger)) - return invoke(min_enabled_level, Tuple{typeof(logger)}, logger) + return invoke(min_enabled_level, Tuple{typeof(logger)}, logger)::LogLevel end function _invoked_catch_exceptions(@nospecialize(logger)) - return invoke(catch_exceptions, Tuple{typeof(logger)}, logger) + return invoke(catch_exceptions, Tuple{typeof(logger)}, logger)::Bool end """ From 12d364e8249a07097a233ce7ea2886002459cc50 Mon Sep 17 00:00:00 2001 From: Kenta Sato Date: Thu, 19 Aug 2021 15:35:58 +0900 Subject: [PATCH 086/135] quote DimensionMismatch in docstring (#41926) --- base/abstractarray.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/abstractarray.jl b/base/abstractarray.jl index d5d47fe855bd53..0a88e733adbc0f 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -300,7 +300,7 @@ If you supply more than one `AbstractArray` argument, `eachindex` will create an iterable object that is fast for all arguments (a [`UnitRange`](@ref) if all inputs have fast linear indexing, a [`CartesianIndices`](@ref) otherwise). -If the arrays have different sizes and/or dimensionalities, a DimensionMismatch exception +If the arrays have different sizes and/or dimensionalities, a `DimensionMismatch` exception will be thrown. # Examples ```jldoctest From 29c9ea07f543d6fdcb7c484575df4cd6c9b07a44 Mon Sep 17 00:00:00 2001 From: Sebastian Stock <42280794+sostock@users.noreply.github.com> Date: Thu, 19 Aug 2021 14:11:21 +0200 Subject: [PATCH 087/135] Support negative strides in `BLAS.gemv!` (#41513) * Support negative strides in `BLAS.gemv!` * Preserve X and Y during ccall --- stdlib/LinearAlgebra/src/blas.jl | 12 ++++++++--- stdlib/LinearAlgebra/test/blas.jl | 36 +++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/stdlib/LinearAlgebra/src/blas.jl b/stdlib/LinearAlgebra/src/blas.jl index c96fc9b965b1e9..3092e87095b445 100644 --- a/stdlib/LinearAlgebra/src/blas.jl +++ b/stdlib/LinearAlgebra/src/blas.jl @@ -664,13 +664,19 @@ for (fname, elty) in ((:dgemv_,:Float64), throw(DimensionMismatch("the transpose of A has dimensions $n, $m, X has length $(length(X)) and Y has length $(length(Y))")) end chkstride1(A) - ccall((@blasfunc($fname), libblastrampoline), Cvoid, + lda = stride(A,2) + lda >= max(1, size(A,1)) || error("`stride(A,2)` must be at least `max(1, size(A,1))`") + sX = stride(X,1) + pX = pointer(X, sX > 0 ? firstindex(X) : lastindex(X)) + sY = stride(Y,1) + pY = pointer(Y, sY > 0 ? firstindex(X) : lastindex(X)) + GC.@preserve X Y ccall((@blasfunc($fname), libblastrampoline), Cvoid, (Ref{UInt8}, Ref{BlasInt}, Ref{BlasInt}, Ref{$elty}, Ptr{$elty}, Ref{BlasInt}, Ptr{$elty}, Ref{BlasInt}, Ref{$elty}, Ptr{$elty}, Ref{BlasInt}, Clong), trans, size(A,1), size(A,2), alpha, - A, max(1,stride(A,2)), X, stride(X,1), - beta, Y, stride(Y,1), 1) + A, lda, pX, sX, + beta, pY, sY, 1) Y end function gemv(trans::AbstractChar, alpha::($elty), A::AbstractMatrix{$elty}, X::AbstractVector{$elty}) diff --git a/stdlib/LinearAlgebra/test/blas.jl b/stdlib/LinearAlgebra/test/blas.jl index 911b684b1793b1..f317c8ee12538f 100644 --- a/stdlib/LinearAlgebra/test/blas.jl +++ b/stdlib/LinearAlgebra/test/blas.jl @@ -370,6 +370,41 @@ Random.seed!(100) @test all(o4cp .== z4) @test all(BLAS.gemv('N', U4, o4) .== v41) @test all(BLAS.gemv('N', U4, o4) .== v41) + @testset "non-standard strides" begin + if elty <: Complex + A = elty[1+2im 3+4im 5+6im 7+8im; 2+3im 4+5im 6+7im 8+9im; 3+4im 5+6im 7+8im 9+10im] + v = elty[1+2im, 2+3im, 3+4im, 4+5im] + dest = view(ones(elty, 5), 4:-2:2) + @test BLAS.gemv!('N', elty(2), view(A, 2:3, 2:2:4), view(v, 1:3:4), elty(3), dest) == elty[-35+178im, -39+202im] + @test BLAS.gemv('N', elty(-1), view(A, 2:3, 2:3), view(v, 2:-1:1)) == elty[15-41im, 17-49im] + @test BLAS.gemv('N', view(A, 1:0, 1:2), view(v, 1:2)) == elty[] + dest = view(ones(elty, 5), 4:-2:2) + @test BLAS.gemv!('T', elty(2), view(A, 2:3, 2:2:4), view(v, 1:3:4), elty(3), dest) == elty[-29+124im, -45+220im] + @test BLAS.gemv('T', elty(-1), view(A, 2:3, 2:3), view(v, 2:-1:1)) == elty[14-38im, 18-54im] + @test BLAS.gemv('T', view(A, 2:3, 2:1), view(v, 1:2)) == elty[] + dest = view(ones(elty, 5), 4:-2:2) + @test BLAS.gemv!('C', elty(2), view(A, 2:3, 2:2:4), view(v, 1:3:4), elty(3), dest) == elty[131+8im, 227+24im] + @test BLAS.gemv('C', elty(-1), view(A, 2:3, 2:3), view(v, 2:-1:1)) == elty[-40-6im, -56-10im] + @test BLAS.gemv('C', view(A, 2:3, 2:1), view(v, 1:2)) == elty[] + else + A = elty[1 2 3 4; 5 6 7 8; 9 10 11 12] + v = elty[1, 2, 3, 4] + dest = view(ones(elty, 5), 4:-2:2) + @test BLAS.gemv!('N', elty(2), view(A, 2:3, 2:2:4), view(v, 1:3:4), elty(3), dest) == elty[79, 119] + @test BLAS.gemv('N', elty(-1), view(A, 2:3, 2:3), view(v, 2:-1:1)) == elty[-19, -31] + @test BLAS.gemv('N', view(A, 1:0, 1:2), view(v, 1:2)) == elty[] + for trans = ('T', 'C') + dest = view(ones(elty, 5), 4:-2:2) + @test BLAS.gemv!(trans, elty(2), view(A, 2:3, 2:2:4), view(v, 1:3:4), elty(3), dest) == elty[95, 115] + @test BLAS.gemv(trans, elty(-1), view(A, 2:3, 2:3), view(v, 2:-1:1)) == elty[-22, -25] + @test BLAS.gemv(trans, view(A, 2:3, 2:1), view(v, 1:2)) == elty[] + end + end + for trans = ('N', 'T', 'C') + @test_throws ErrorException BLAS.gemv(trans, view(A, 1:2:3, 1:2), view(v, 1:2)) + @test_throws ErrorException BLAS.gemv(trans, view(A, 1:2, 2:-1:1), view(v, 1:2)) + end + end end @testset "gemm" begin @test all(BLAS.gemm('N', 'N', I4, I4) .== I4) @@ -459,6 +494,7 @@ Base.setindex!(A::WrappedArray{T, N}, v, I::Vararg{Int, N}) where {T, N} = setin Base.unsafe_convert(::Type{Ptr{T}}, A::WrappedArray{T}) where T = Base.unsafe_convert(Ptr{T}, A.A) Base.strides(A::WrappedArray) = strides(A.A) +Base.elsize(::Type{WrappedArray{T,N}}) where {T,N} = Base.elsize(Array{T,N}) @testset "strided interface adjtrans" begin x = WrappedArray([1, 2, 3, 4]) From 0258553a82aba0a609978d1719e05a20ebdf4826 Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Thu, 19 Aug 2021 12:41:32 -0400 Subject: [PATCH 088/135] small optimization to subtyping (#41672) Zero and copy only the used portion of the union state buffer. --- src/subtype.c | 101 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 65 insertions(+), 36 deletions(-) diff --git a/src/subtype.c b/src/subtype.c index 158a9dd70b3f37..152d17daeaaaae 100644 --- a/src/subtype.c +++ b/src/subtype.c @@ -42,11 +42,19 @@ extern "C" { // TODO: the stack probably needs to be artificially large because of some // deeper problem (see #21191) and could be shrunk once that is fixed typedef struct { - int depth; - int more; + int16_t depth; + int16_t more; + int16_t used; uint32_t stack[100]; // stack of bits represented as a bit vector } jl_unionstate_t; +typedef struct { + int16_t depth; + int16_t more; + int16_t used; + void *stack; +} jl_saved_unionstate_t; + // Linked list storing the type variable environment. A new jl_varbinding_t // is pushed for each UnionAll type we encounter. `lb` and `ub` are updated // during the computation. @@ -68,14 +76,14 @@ typedef struct jl_varbinding_t { // and we would need to return `intersect(var,other)`. in this case // we choose to over-estimate the intersection by returning the var. int8_t constraintkind; - int depth0; // # of invariant constructors nested around the UnionAll type for this var + int8_t intvalued; // must be integer-valued; i.e. occurs as N in Vararg{_,N} + int16_t depth0; // # of invariant constructors nested around the UnionAll type for this var // when this variable's integer value is compared to that of another, // it equals `other + offset`. used by vararg length parameters. - int offset; + int16_t offset; // array of typevars that our bounds depend on, whose UnionAlls need to be // moved outside ours. jl_array_t *innervars; - int intvalued; // must be integer-valued; i.e. occurs as N in Vararg{_,N} struct jl_varbinding_t *prev; } jl_varbinding_t; @@ -129,6 +137,23 @@ static void statestack_set(jl_unionstate_t *st, int i, int val) JL_NOTSAFEPOINT st->stack[i>>5] &= ~(1u<<(i&31)); } +#define push_unionstate(saved, src) \ + do { \ + (saved)->depth = (src)->depth; \ + (saved)->more = (src)->more; \ + (saved)->used = (src)->used; \ + (saved)->stack = alloca(((src)->used+7)/8); \ + memcpy((saved)->stack, &(src)->stack, ((src)->used+7)/8); \ + } while (0); + +#define pop_unionstate(dst, saved) \ + do { \ + (dst)->depth = (saved)->depth; \ + (dst)->more = (saved)->more; \ + (dst)->used = (saved)->used; \ + memcpy(&(dst)->stack, (saved)->stack, ((saved)->used+7)/8); \ + } while (0); + typedef struct { int8_t *buf; int rdepth; @@ -486,6 +511,10 @@ static jl_value_t *pick_union_element(jl_value_t *u JL_PROPAGATES_ROOT, jl_stenv { jl_unionstate_t *state = R ? &e->Runions : &e->Lunions; do { + if (state->depth >= state->used) { + statestack_set(state, state->used, 0); + state->used++; + } int ui = statestack_get(state, state->depth); state->depth++; if (ui == 0) { @@ -514,11 +543,10 @@ static int subtype_ccheck(jl_value_t *x, jl_value_t *y, jl_stenv_t *e) return 1; if (x == (jl_value_t*)jl_any_type && jl_is_datatype(y)) return 0; - jl_unionstate_t oldLunions = e->Lunions; - jl_unionstate_t oldRunions = e->Runions; + jl_saved_unionstate_t oldLunions; push_unionstate(&oldLunions, &e->Lunions); + jl_saved_unionstate_t oldRunions; push_unionstate(&oldRunions, &e->Runions); int sub; - memset(e->Lunions.stack, 0, sizeof(e->Lunions.stack)); - memset(e->Runions.stack, 0, sizeof(e->Runions.stack)); + e->Lunions.used = e->Runions.used = 0; e->Runions.depth = 0; e->Runions.more = 0; e->Lunions.depth = 0; @@ -526,8 +554,8 @@ static int subtype_ccheck(jl_value_t *x, jl_value_t *y, jl_stenv_t *e) sub = forall_exists_subtype(x, y, e, 0); - e->Runions = oldRunions; - e->Lunions = oldLunions; + pop_unionstate(&e->Runions, &oldRunions); + pop_unionstate(&e->Lunions, &oldLunions); return sub; } @@ -731,8 +759,8 @@ static jl_unionall_t *unalias_unionall(jl_unionall_t *u, jl_stenv_t *e) static int subtype_unionall(jl_value_t *t, jl_unionall_t *u, jl_stenv_t *e, int8_t R, int param) { u = unalias_unionall(u, e); - jl_varbinding_t vb = { u->var, u->var->lb, u->var->ub, R, 0, 0, 0, 0, - R ? e->Rinvdepth : e->invdepth, 0, NULL, 0, e->vars }; + jl_varbinding_t vb = { u->var, u->var->lb, u->var->ub, R, 0, 0, 0, 0, 0, + R ? e->Rinvdepth : e->invdepth, 0, NULL, e->vars }; JL_GC_PUSH4(&u, &vb.lb, &vb.ub, &vb.innervars); e->vars = &vb; int ans; @@ -1148,6 +1176,10 @@ static int subtype(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, int param) // union against the variable before trying to take it apart to see if there are any // variables lurking inside. jl_unionstate_t *state = &e->Runions; + if (state->depth >= state->used) { + statestack_set(state, state->used, 0); + state->used++; + } ui = statestack_get(state, state->depth); state->depth++; if (ui == 0) @@ -1310,13 +1342,13 @@ static int forall_exists_equal(jl_value_t *x, jl_value_t *y, jl_stenv_t *e) (is_definite_length_tuple_type(x) && is_indefinite_length_tuple_type(y))) return 0; - jl_unionstate_t oldLunions = e->Lunions; - memset(e->Lunions.stack, 0, sizeof(e->Lunions.stack)); + jl_saved_unionstate_t oldLunions; push_unionstate(&oldLunions, &e->Lunions); + e->Lunions.used = 0; int sub; if (!jl_has_free_typevars(x) || !jl_has_free_typevars(y)) { - jl_unionstate_t oldRunions = e->Runions; - memset(e->Runions.stack, 0, sizeof(e->Runions.stack)); + jl_saved_unionstate_t oldRunions; push_unionstate(&oldRunions, &e->Runions); + e->Runions.used = 0; e->Runions.depth = 0; e->Runions.more = 0; e->Lunions.depth = 0; @@ -1324,7 +1356,7 @@ static int forall_exists_equal(jl_value_t *x, jl_value_t *y, jl_stenv_t *e) sub = forall_exists_subtype(x, y, e, 2); - e->Runions = oldRunions; + pop_unionstate(&e->Runions, &oldRunions); } else { int lastset = 0; @@ -1342,13 +1374,13 @@ static int forall_exists_equal(jl_value_t *x, jl_value_t *y, jl_stenv_t *e) } } - e->Lunions = oldLunions; + pop_unionstate(&e->Lunions, &oldLunions); return sub && subtype(y, x, e, 0); } static int exists_subtype(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, jl_value_t *saved, jl_savedenv_t *se, int param) { - memset(e->Runions.stack, 0, sizeof(e->Runions.stack)); + e->Runions.used = 0; int lastset = 0; while (1) { e->Runions.depth = 0; @@ -1379,7 +1411,7 @@ static int forall_exists_subtype(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, in JL_GC_PUSH1(&saved); save_env(e, &saved, &se); - memset(e->Lunions.stack, 0, sizeof(e->Lunions.stack)); + e->Lunions.used = 0; int lastset = 0; int sub; while (1) { @@ -1415,6 +1447,7 @@ static void init_stenv(jl_stenv_t *e, jl_value_t **env, int envsz) e->emptiness_only = 0; e->Lunions.depth = 0; e->Runions.depth = 0; e->Lunions.more = 0; e->Runions.more = 0; + e->Lunions.used = 0; e->Runions.used = 0; } // subtyping entry points @@ -2084,14 +2117,14 @@ static jl_value_t *intersect_aside(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, if (y == (jl_value_t*)jl_any_type && !jl_is_typevar(x)) return x; - jl_unionstate_t oldRunions = e->Runions; + jl_saved_unionstate_t oldRunions; push_unionstate(&oldRunions, &e->Runions); int savedepth = e->invdepth, Rsavedepth = e->Rinvdepth; // TODO: this doesn't quite make sense e->invdepth = e->Rinvdepth = d; jl_value_t *res = intersect_all(x, y, e); - e->Runions = oldRunions; + pop_unionstate(&e->Runions, &oldRunions); e->invdepth = savedepth; e->Rinvdepth = Rsavedepth; return res; @@ -2102,10 +2135,10 @@ static jl_value_t *intersect_union(jl_value_t *x, jl_uniontype_t *u, jl_stenv_t if (param == 2 || (!jl_has_free_typevars(x) && !jl_has_free_typevars((jl_value_t*)u))) { jl_value_t *a=NULL, *b=NULL; JL_GC_PUSH2(&a, &b); - jl_unionstate_t oldRunions = e->Runions; + jl_saved_unionstate_t oldRunions; push_unionstate(&oldRunions, &e->Runions); a = R ? intersect_all(x, u->a, e) : intersect_all(u->a, x, e); b = R ? intersect_all(x, u->b, e) : intersect_all(u->b, x, e); - e->Runions = oldRunions; + pop_unionstate(&e->Runions, &oldRunions); jl_value_t *i = simple_join(a,b); JL_GC_POP(); return i; @@ -2600,8 +2633,8 @@ static jl_value_t *intersect_unionall(jl_value_t *t, jl_unionall_t *u, jl_stenv_ { jl_value_t *res=NULL, *res2=NULL, *save=NULL, *save2=NULL; jl_savedenv_t se, se2; - jl_varbinding_t vb = { u->var, u->var->lb, u->var->ub, R, 0, 0, 0, 0, - R ? e->Rinvdepth : e->invdepth, 0, NULL, 0, e->vars }; + jl_varbinding_t vb = { u->var, u->var->lb, u->var->ub, R, 0, 0, 0, 0, 0, + R ? e->Rinvdepth : e->invdepth, 0, NULL, e->vars }; JL_GC_PUSH6(&res, &save2, &vb.lb, &vb.ub, &save, &vb.innervars); save_env(e, &save, &se); res = intersect_unionall_(t, u, e, R, param, &vb); @@ -3159,7 +3192,7 @@ static jl_value_t *intersect_all(jl_value_t *x, jl_value_t *y, jl_stenv_t *e) { e->Runions.depth = 0; e->Runions.more = 0; - memset(e->Runions.stack, 0, sizeof(e->Runions.stack)); + e->Runions.used = 0; jl_value_t **is; JL_GC_PUSHARGS(is, 3); jl_value_t **saved = &is[2]; @@ -3176,11 +3209,8 @@ static jl_value_t *intersect_all(jl_value_t *x, jl_value_t *y, jl_stenv_t *e) save_env(e, saved, &se); } while (e->Runions.more) { - if (e->emptiness_only && ii != jl_bottom_type) { - free_env(&se); - JL_GC_POP(); - return ii; - } + if (e->emptiness_only && ii != jl_bottom_type) + break; e->Runions.depth = 0; int set = e->Runions.more - 1; e->Runions.more = 0; @@ -3209,9 +3239,8 @@ static jl_value_t *intersect_all(jl_value_t *x, jl_value_t *y, jl_stenv_t *e) } total_iter++; if (niter > 3 || total_iter > 400000) { - free_env(&se); - JL_GC_POP(); - return y; + ii = y; + break; } } free_env(&se); From 0224c42bce6daec1b5580b8a8a6b43f9437d2cee Mon Sep 17 00:00:00 2001 From: Elliot Saba Date: Thu, 19 Aug 2021 11:23:02 -0700 Subject: [PATCH 089/135] Work around registry corruption issues (#41934) Because our jobs get interrupted, it seems that incomplete registry trees are created pretty often. Let's just not persist them for now. --- .buildkite/pipelines/main/platforms/linux64.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.buildkite/pipelines/main/platforms/linux64.yml b/.buildkite/pipelines/main/platforms/linux64.yml index 44b0ebe29f5570..ad5d32a20b3a03 100644 --- a/.buildkite/pipelines/main/platforms/linux64.yml +++ b/.buildkite/pipelines/main/platforms/linux64.yml @@ -9,6 +9,8 @@ steps: key: package_linux64 plugins: - JuliaCI/julia#v1: + # Drop default "registries" directory, so it is not persisted from execution to execution + persist_depot_dirs: packages,artifacts,compiled version: 1.6 - staticfloat/sandbox#v1: rootfs_url: https://github.com/JuliaCI/rootfs-images/releases/download/v3.1/package_linux.x86_64.tar.gz From 19760450643aff7270323019a9a1cbb39cf9dbfe Mon Sep 17 00:00:00 2001 From: Mark Kittisopikul Date: Fri, 20 Aug 2021 16:02:01 -0400 Subject: [PATCH 090/135] permit AbstractUnitRange for BitArray indexing (#41810) --- base/bitarray.jl | 10 +++++----- base/multidimensional.jl | 12 ++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/base/bitarray.jl b/base/bitarray.jl index 1db84cad37a1c8..6fe94df3785160 100644 --- a/base/bitarray.jl +++ b/base/bitarray.jl @@ -703,7 +703,7 @@ end indexoffset(i) = first(i)-1 indexoffset(::Colon) = 0 -@propagate_inbounds function setindex!(B::BitArray, X::AbstractArray, J0::Union{Colon,UnitRange{Int}}) +@propagate_inbounds function setindex!(B::BitArray, X::AbstractArray, J0::Union{Colon,AbstractUnitRange{Int}}) _setindex!(IndexStyle(B), B, X, to_indices(B, (J0,))[1]) end @@ -954,7 +954,7 @@ function deleteat!(B::BitVector, i::Integer) return _deleteat!(B, i) end -function deleteat!(B::BitVector, r::UnitRange{Int}) +function deleteat!(B::BitVector, r::AbstractUnitRange{Int}) n = length(B) i_f = first(r) i_l = last(r) @@ -1031,8 +1031,8 @@ end const _default_bit_splice = BitVector() -function splice!(B::BitVector, r::Union{UnitRange{Int}, Integer}, ins::AbstractArray = _default_bit_splice) - _splice_int!(B, isa(r, UnitRange{Int}) ? r : Int(r), ins) +function splice!(B::BitVector, r::Union{AbstractUnitRange{Int}, Integer}, ins::AbstractArray = _default_bit_splice) + _splice_int!(B, isa(r, AbstractUnitRange{Int}) ? r : Int(r), ins) end function _splice_int!(B::BitVector, r, ins) n = length(B) @@ -1073,7 +1073,7 @@ function _splice_int!(B::BitVector, r, ins) return v end -function splice!(B::BitVector, r::Union{UnitRange{Int}, Integer}, ins) +function splice!(B::BitVector, r::Union{AbstractUnitRange{Int}, Integer}, ins) Bins = BitVector(undef, length(ins)) i = 1 for x in ins diff --git a/base/multidimensional.jl b/base/multidimensional.jl index 61e6be86025127..9694a8b9da650a 100644 --- a/base/multidimensional.jl +++ b/base/multidimensional.jl @@ -1251,14 +1251,14 @@ end # contiguous multidimensional indexing: if the first dimension is a range, # we can get some performance from using copy_chunks! -@inline function _unsafe_getindex!(X::BitArray, B::BitArray, I0::Union{UnitRange{Int},Slice}) +@inline function _unsafe_getindex!(X::BitArray, B::BitArray, I0::Union{AbstractUnitRange{Int},Slice}) copy_chunks!(X.chunks, 1, B.chunks, indexoffset(I0)+1, length(I0)) return X end # Optimization where the inner dimension is contiguous improves perf dramatically @generated function _unsafe_getindex!(X::BitArray, B::BitArray, - I0::Union{Slice,UnitRange{Int}}, I::Union{Int,UnitRange{Int},Slice}...) + I0::Union{Slice,UnitRange{Int}}, I::Union{Int,AbstractUnitRange{Int},Slice}...) N = length(I) quote $(Expr(:meta, :inline)) @@ -1393,7 +1393,7 @@ end # contiguous multidimensional indexing: if the first dimension is a range, # we can get some performance from using copy_chunks! -@inline function setindex!(B::BitArray, X::Union{StridedArray,BitArray}, J0::Union{Colon,UnitRange{Int}}) +@inline function setindex!(B::BitArray, X::Union{StridedArray,BitArray}, J0::Union{Colon,AbstractUnitRange{Int}}) I0 = to_indices(B, (J0,))[1] @boundscheck checkbounds(B, I0) l0 = length(I0) @@ -1405,13 +1405,13 @@ end end @inline function setindex!(B::BitArray, X::Union{StridedArray,BitArray}, - I0::Union{Colon,UnitRange{Int}}, I::Union{Int,UnitRange{Int},Colon}...) + I0::Union{Colon,AbstractUnitRange{Int}}, I::Union{Int,AbstractUnitRange{Int},Colon}...) J = to_indices(B, (I0, I...)) @boundscheck checkbounds(B, J...) _unsafe_setindex!(B, X, J...) end @generated function _unsafe_setindex!(B::BitArray, X::Union{StridedArray,BitArray}, - I0::Union{Slice,UnitRange{Int}}, I::Union{Int,UnitRange{Int},Slice}...) + I0::Union{Slice,AbstractUnitRange{Int}}, I::Union{Int,AbstractUnitRange{Int},Slice}...) N = length(I) quote idxlens = @ncall $N index_lengths I0 d->I[d] @@ -1446,7 +1446,7 @@ end end @propagate_inbounds function setindex!(B::BitArray, X::AbstractArray, - I0::Union{Colon,UnitRange{Int}}, I::Union{Int,UnitRange{Int},Colon}...) + I0::Union{Colon,AbstractUnitRange{Int}}, I::Union{Int,AbstractUnitRange{Int},Colon}...) _setindex!(IndexStyle(B), B, X, to_indices(B, (I0, I...))...) end From 14e1ba0127d21747e208e60514334c51b4a81b64 Mon Sep 17 00:00:00 2001 From: Mark Kittisopikul Date: Fri, 20 Aug 2021 16:02:47 -0400 Subject: [PATCH 091/135] permit AbstractUnitRange for setindex!,deleteat!,splice! (#41809) --- base/array.jl | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/base/array.jl b/base/array.jl index 15c354dce60857..b09a7bd4de836b 100644 --- a/base/array.jl +++ b/base/array.jl @@ -895,7 +895,7 @@ function getindex end @eval getindex(A::Array, i1::Int) = arrayref($(Expr(:boundscheck)), A, i1) @eval getindex(A::Array, i1::Int, i2::Int, I::Int...) = (@_inline_meta; arrayref($(Expr(:boundscheck)), A, i1, i2, I...)) -# Faster contiguous indexing using copyto! for UnitRange and Colon +# Faster contiguous indexing using copyto! for AbstractUnitRange and Colon function getindex(A::Array, I::AbstractUnitRange{<:Integer}) @_inline_meta @boundscheck checkbounds(A, I) @@ -955,7 +955,7 @@ function setindex!(A::Array, X::AbstractArray, I::AbstractVector{Int}) end # Faster contiguous setindex! with copyto! -function setindex!(A::Array{T}, X::Array{T}, I::UnitRange{Int}) where T +function setindex!(A::Array{T}, X::Array{T}, I::AbstractUnitRange{Int}) where T @_inline_meta @boundscheck checkbounds(A, I) lI = length(I) @@ -1455,7 +1455,7 @@ julia> deleteat!([6, 5, 4, 3, 2, 1], 2) """ deleteat!(a::Vector, i::Integer) = (_deleteat!(a, i, 1); a) -function deleteat!(a::Vector, r::UnitRange{<:Integer}) +function deleteat!(a::Vector, r::AbstractUnitRange{<:Integer}) n = length(a) isempty(r) || _deleteat!(a, first(r), length(r)) return a @@ -1621,7 +1621,7 @@ Remove items at specified indices, and return a collection containing the removed items. Subsequent items are shifted left to fill the resulting gaps. If specified, replacement values from an ordered collection will be spliced in -place of the removed items; in this case, `indices` must be a `UnitRange`. +place of the removed items; in this case, `indices` must be a `AbstractUnitRange`. To insert `replacement` before an index `n` without removing any items, use `splice!(collection, n:n-1, replacement)`. @@ -1629,6 +1629,9 @@ To insert `replacement` before an index `n` without removing any items, use !!! compat "Julia 1.5" Prior to Julia 1.5, `indices` must always be a `UnitRange`. +!!! compat "Julia 1.8" + Prior to Julia 1.8, `indices` must be a `UnitRange` if splicing in replacement values. + # Examples ```jldoctest julia> A = [-1, -2, -3, 5, 4, 3, -1]; splice!(A, 4:3, 2) @@ -1646,7 +1649,7 @@ julia> A -1 ``` """ -function splice!(a::Vector, r::UnitRange{<:Integer}, ins=_default_splice) +function splice!(a::Vector, r::AbstractUnitRange{<:Integer}, ins=_default_splice) v = a[r] m = length(ins) if m == 0 From eb83c4d25b9c4a3696c08d2b5c7debfa9cc1a5ae Mon Sep 17 00:00:00 2001 From: Mark Kittisopikul Date: Fri, 20 Aug 2021 16:03:16 -0400 Subject: [PATCH 092/135] Generalize copyto! and copy_transpose! for AbstractUnitRange (#41805) --- 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 fb75669e647faf..2b315b0cf6080a 100644 --- a/stdlib/LinearAlgebra/src/matmul.jl +++ b/stdlib/LinearAlgebra/src/matmul.jl @@ -9,7 +9,7 @@ matprod(x, y) = x*y + x*y dot(x::Union{DenseArray{T},StridedVector{T}}, y::Union{DenseArray{T},StridedVector{T}}) where {T<:BlasReal} = BLAS.dot(x, y) dot(x::Union{DenseArray{T},StridedVector{T}}, y::Union{DenseArray{T},StridedVector{T}}) where {T<:BlasComplex} = BLAS.dotc(x, y) -function dot(x::Vector{T}, rx::Union{UnitRange{TI},AbstractRange{TI}}, y::Vector{T}, ry::Union{UnitRange{TI},AbstractRange{TI}}) where {T<:BlasReal,TI<:Integer} +function dot(x::Vector{T}, rx::AbstractRange{TI}, y::Vector{T}, ry::AbstractRange{TI}) where {T<:BlasReal,TI<:Integer} if length(rx) != length(ry) throw(DimensionMismatch("length of rx, $(length(rx)), does not equal length of ry, $(length(ry))")) end @@ -22,7 +22,7 @@ function dot(x::Vector{T}, rx::Union{UnitRange{TI},AbstractRange{TI}}, y::Vector GC.@preserve x y BLAS.dot(length(rx), pointer(x)+(first(rx)-1)*sizeof(T), step(rx), pointer(y)+(first(ry)-1)*sizeof(T), step(ry)) end -function dot(x::Vector{T}, rx::Union{UnitRange{TI},AbstractRange{TI}}, y::Vector{T}, ry::Union{UnitRange{TI},AbstractRange{TI}}) where {T<:BlasComplex,TI<:Integer} +function dot(x::Vector{T}, rx::AbstractRange{TI}, y::Vector{T}, ry::AbstractRange{TI}) where {T<:BlasComplex,TI<:Integer} if length(rx) != length(ry) throw(DimensionMismatch("length of rx, $(length(rx)), does not equal length of ry, $(length(ry))")) end @@ -625,7 +625,7 @@ end lapack_size(t::AbstractChar, M::AbstractVecOrMat) = (size(M, t=='N' ? 1 : 2), size(M, t=='N' ? 2 : 1)) -function copyto!(B::AbstractVecOrMat, ir_dest::UnitRange{Int}, jr_dest::UnitRange{Int}, tM::AbstractChar, M::AbstractVecOrMat, ir_src::UnitRange{Int}, jr_src::UnitRange{Int}) +function copyto!(B::AbstractVecOrMat, ir_dest::AbstractUnitRange{Int}, jr_dest::AbstractUnitRange{Int}, tM::AbstractChar, M::AbstractVecOrMat, ir_src::AbstractUnitRange{Int}, jr_src::AbstractUnitRange{Int}) if tM == 'N' copyto!(B, ir_dest, jr_dest, M, ir_src, jr_src) else @@ -635,7 +635,7 @@ function copyto!(B::AbstractVecOrMat, ir_dest::UnitRange{Int}, jr_dest::UnitRang B end -function copy_transpose!(B::AbstractMatrix, ir_dest::UnitRange{Int}, jr_dest::UnitRange{Int}, tM::AbstractChar, M::AbstractVecOrMat, ir_src::UnitRange{Int}, jr_src::UnitRange{Int}) +function copy_transpose!(B::AbstractMatrix, ir_dest::AbstractUnitRange{Int}, jr_dest::AbstractUnitRange{Int}, tM::AbstractChar, M::AbstractVecOrMat, ir_src::AbstractUnitRange{Int}, jr_src::AbstractUnitRange{Int}) if tM == 'N' LinearAlgebra.copy_transpose!(B, ir_dest, jr_dest, M, ir_src, jr_src) else From e37e2906a4b13c6ff671f52e8ef88ea3fc815515 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Sat, 21 Aug 2021 18:47:49 +0100 Subject: [PATCH 093/135] doc: fix typo in methods docs (#41937) --- doc/src/manual/methods.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/manual/methods.md b/doc/src/manual/methods.md index a94d674501e045..1985292d66611a 100644 --- a/doc/src/manual/methods.md +++ b/doc/src/manual/methods.md @@ -41,7 +41,7 @@ for structuring and organizing programs. it can be omitted altogether, writing just `meth(arg1,arg2)`, with `this` implied as the receiving object. !!! note - All the examples in this chapter assume that you are defining modules for a function in the *same* + All the examples in this chapter assume that you are defining methods for a function in the *same* module. If you want to add methods to a function in *another* module, you have to `import` it or use the name qualified with module names. See the section on [namespace management](@ref namespace-management). From 310bf160e026f3867119bef7d14724279e4eec60 Mon Sep 17 00:00:00 2001 From: Dilum Aluthge Date: Sun, 22 Aug 2021 22:42:24 -0400 Subject: [PATCH 094/135] README: add a link to the `base-buildkite-docs` repository (#41956) --- .buildkite/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.buildkite/README.md b/.buildkite/README.md index 12887536b90c1d..b3f74f2b231378 100644 --- a/.buildkite/README.md +++ b/.buildkite/README.md @@ -3,3 +3,5 @@ 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. + +The documentation for the Base Julia CI setup is located in the [base-buildkite-docs](https://github.com/JuliaCI/base-buildkite-docs) repository. From 6e1bae4b4e07c31bc563415a8c3480f17b27dcae Mon Sep 17 00:00:00 2001 From: Tim Besard Date: Mon, 23 Aug 2021 09:12:51 +0200 Subject: [PATCH 095/135] Derive better name for methods with external method tables. (#41930) --- src/interpreter.c | 1 + src/method.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/interpreter.c b/src/interpreter.c index 1ae6507ef334ee..4686efe054edf3 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -79,6 +79,7 @@ static jl_value_t *eval_methoddef(jl_expr_t *ex, interpreter_state *s) { jl_value_t **args = jl_array_ptr_data(ex->args); + // generic function definition if (jl_expr_nargs(ex) == 1) { jl_value_t **args = jl_array_ptr_data(ex->args); jl_sym_t *fname = (jl_sym_t*)args[0]; diff --git a/src/method.c b/src/method.c index 48b074e8009040..22145a43498533 100644 --- a/src/method.c +++ b/src/method.c @@ -831,7 +831,7 @@ JL_DLLEXPORT jl_method_t* jl_method_def(jl_svec_t *argdata, // TODO: derive our debug name from the syntax instead of the type name = mt->name; - if (mt == jl_type_type_mt || mt == jl_nonfunction_mt) { + if (mt == jl_type_type_mt || mt == jl_nonfunction_mt || external_mt) { // our value for `name` is bad, try to guess what the syntax might have had, // like `jl_static_show_func_sig` might have come up with jl_datatype_t *dt = jl_first_argument_datatype(argtype); From 9cad1e0af8716270a3c0bcd5c70457596fe6c2e2 Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Mon, 23 Aug 2021 05:42:29 -0500 Subject: [PATCH 096/135] Add test for #38149 (#41958) No code change is needed, but the use-case in that issue doesn't appear to be tested directly. Closes #38149 --- test/precompile.jl | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/precompile.jl b/test/precompile.jl index 51b25b8325b2aa..49f754186c50f1 100644 --- a/test/precompile.jl +++ b/test/precompile.jl @@ -875,3 +875,19 @@ precompile_test_harness("Renamed Imports") do load_path Base.compilecache(Base.PkgId("RenameImports")) @test (@eval (using RenameImports; RenameImports.test())) isa Module end + +@testset "issue 38149" begin + M = Module() + @eval M begin + @nospecialize + f(x, y) = x + y + f(x::Int, y) = 2x + y + end + precompile(M.f, (Int, Any)) + precompile(M.f, (AbstractFloat, Any)) + mis = map(methods(M.f)) do m + m.specializations[1] + end + @test any(mi -> mi.specTypes.parameters[2] === Any, mis) + @test all(mi -> isa(mi.cache, Core.CodeInstance), mis) +end From b4ca19664c84e7a331bfc11375bec74bd0b72bdb Mon Sep 17 00:00:00 2001 From: Nathan Daly Date: Thu, 29 Jul 2021 21:52:19 -0400 Subject: [PATCH 097/135] Make jl_cumulative_compile_time_ns global (and reentrant). Now, multiple tasks (on the same or different Threads) can start and stop compilation time measurement, without interrupting each other. * Makes jl_cumulative_compile_time_ns into a global, atomic variable. Instead of keeping per-task compilation time, this change keeps a global counter of compilation time, protected with atomic mutations. Fixes #41739 ```julia julia> include("./compilation-task-migration-17-example.jl") start thread: 2 end thread: 2 5.185706 seconds (3.53 M allocations: 2.570 GiB, 7.34% gc time, 15.57% compilation time) julia> include("./compilation-task-migration-17-example.jl") start thread: 3 WARNING: replacing module M. end thread: 1 4.110316 seconds (18.23 k allocations: 2.391 GiB, 5.67% gc time, 0.24% compilation time) ``` Compilation time measurement originally added in: https://github.com/JuliaLang/julia/pull/38885 Problems addressed: - This fixes https://github.com/JuliaLang/julia/issues/41739, meaning it fixes compilation time reporting in 1.7 after task migration was enabled. - It also fixes the race condition that existed previously, even on 1.6, where multiple Tasks on the thread measuring `@time` could break the measurement, as identified in (https://github.com/JuliaLang/julia/issues/41271#issuecomment-876564749). - It fixes reentrant `@time` by making the `enable` flag a _counter,_ instead of a boolean. - It fixes `@time` called from multiple threads by making that flag thread-safe (via atomics). --- base/timing.jl | 2 +- src/aotcompile.cpp | 16 ++++++++-------- src/gf.c | 12 ++++++++---- src/jitlayers.cpp | 44 ++++++++++++++++++++++---------------------- src/julia_internal.h | 5 +++-- src/task.c | 5 ++++- src/threading.c | 6 ++---- test/misc.jl | 16 ++++++++++++++++ 8 files changed, 64 insertions(+), 42 deletions(-) diff --git a/base/timing.jl b/base/timing.jl index ab7af23048305b..45a27e33789773 100644 --- a/base/timing.jl +++ b/base/timing.jl @@ -55,7 +55,7 @@ function gc_alloc_count(diff::GC_Diff) diff.malloc + diff.realloc + diff.poolalloc + diff.bigalloc end -# cumulative total time spent on compilation +# cumulative total time spent on compilation, in nanoseconds cumulative_compile_time_ns_before() = ccall(:jl_cumulative_compile_time_ns_before, UInt64, ()) cumulative_compile_time_ns_after() = ccall(:jl_cumulative_compile_time_ns_after, UInt64, ()) diff --git a/src/aotcompile.cpp b/src/aotcompile.cpp index cb22bd80773412..cfe3c562c7a597 100644 --- a/src/aotcompile.cpp +++ b/src/aotcompile.cpp @@ -278,8 +278,8 @@ void *jl_create_native(jl_array_t *methods, const jl_cgparams_t cgparams, int _p JL_GC_PUSH1(&src); JL_LOCK(&codegen_lock); uint64_t compiler_start_time = 0; - int tid = jl_threadid(); - if (jl_measure_compile_time[tid]) + uint8_t measure_compile_time_enabled = jl_atomic_load_relaxed(&jl_measure_compile_time_enabled); + if (measure_compile_time_enabled) compiler_start_time = jl_hrtime(); CompilationPolicy policy = (CompilationPolicy) _policy; @@ -407,8 +407,8 @@ void *jl_create_native(jl_array_t *methods, const jl_cgparams_t cgparams, int _p } data->M = std::move(clone); - if (jl_measure_compile_time[tid]) - jl_cumulative_compile_time[tid] += (jl_hrtime() - compiler_start_time); + if (measure_compile_time_enabled) + jl_atomic_fetch_add_relaxed(&jl_cumulative_compile_time, (jl_hrtime() - compiler_start_time)); if (policy == CompilationPolicy::ImagingMode) imaging_mode = 0; JL_UNLOCK(&codegen_lock); // Might GC @@ -908,8 +908,8 @@ void *jl_get_llvmf_defn(jl_method_instance_t *mi, size_t world, char getwrapper, jl_llvm_functions_t decls; JL_LOCK(&codegen_lock); uint64_t compiler_start_time = 0; - int tid = jl_threadid(); - if (jl_measure_compile_time[tid]) + uint8_t measure_compile_time_enabled = jl_atomic_load_relaxed(&jl_measure_compile_time_enabled); + if (measure_compile_time_enabled) compiler_start_time = jl_hrtime(); std::tie(m, decls) = jl_emit_code(mi, src, jlrettype, output); @@ -934,8 +934,8 @@ void *jl_get_llvmf_defn(jl_method_instance_t *mi, size_t world, char getwrapper, m.release(); // the return object `llvmf` will be the owning pointer } JL_GC_POP(); - if (jl_measure_compile_time[tid]) - jl_cumulative_compile_time[tid] += (jl_hrtime() - compiler_start_time); + if (measure_compile_time_enabled) + jl_atomic_fetch_add_relaxed(&jl_cumulative_compile_time, (jl_hrtime() - compiler_start_time)); JL_UNLOCK(&codegen_lock); // Might GC if (F) return F; diff --git a/src/gf.c b/src/gf.c index 52180279ab5c2b..a8b3d3bf020e83 100644 --- a/src/gf.c +++ b/src/gf.c @@ -3160,19 +3160,23 @@ int jl_has_concrete_subtype(jl_value_t *typ) #define typeinf_lock codegen_lock static uint64_t inference_start_time = 0; +static uint8_t inference_is_measuring_compile_time = 0; JL_DLLEXPORT void jl_typeinf_begin(void) { JL_LOCK(&typeinf_lock); - if (jl_measure_compile_time[jl_threadid()]) + if (jl_atomic_load_relaxed(&jl_measure_compile_time_enabled)) { inference_start_time = jl_hrtime(); + inference_is_measuring_compile_time = 1; + } } JL_DLLEXPORT void jl_typeinf_end(void) { - int tid = jl_threadid(); - if (typeinf_lock.count == 1 && jl_measure_compile_time[tid]) - jl_cumulative_compile_time[tid] += (jl_hrtime() - inference_start_time); + if (typeinf_lock.count == 1 && inference_is_measuring_compile_time) { + jl_atomic_fetch_add_relaxed(&jl_cumulative_compile_time, (jl_hrtime() - inference_start_time)); + inference_is_measuring_compile_time = 0; + } JL_UNLOCK(&typeinf_lock); } diff --git a/src/jitlayers.cpp b/src/jitlayers.cpp index 5717bcced90bf8..60b1903aaa802f 100644 --- a/src/jitlayers.cpp +++ b/src/jitlayers.cpp @@ -76,16 +76,16 @@ void jl_jit_globals(std::map &globals) extern "C" JL_DLLEXPORT uint64_t jl_cumulative_compile_time_ns_before() { - int tid = jl_threadid(); - jl_measure_compile_time[tid] = 1; - return jl_cumulative_compile_time[tid]; + // Increment the flag to allow reentrant callers to `@time`. + jl_atomic_fetch_add(&jl_measure_compile_time_enabled, 1); + return jl_atomic_load_relaxed(&jl_cumulative_compile_time); } extern "C" JL_DLLEXPORT uint64_t jl_cumulative_compile_time_ns_after() { - int tid = jl_threadid(); - jl_measure_compile_time[tid] = 0; - return jl_cumulative_compile_time[tid]; + // Decrement the flag when done measuring, allowing other callers to continue measuring. + jl_atomic_fetch_add(&jl_measure_compile_time_enabled, -1); + return jl_atomic_load_relaxed(&jl_cumulative_compile_time); } // this generates llvm code for the lambda info @@ -231,8 +231,8 @@ int jl_compile_extern_c(void *llvmmod, void *p, void *sysimg, jl_value_t *declrt { JL_LOCK(&codegen_lock); uint64_t compiler_start_time = 0; - int tid = jl_threadid(); - if (jl_measure_compile_time[tid]) + uint8_t measure_compile_time_enabled = jl_atomic_load_relaxed(&jl_measure_compile_time_enabled); + if (measure_compile_time_enabled) compiler_start_time = jl_hrtime(); jl_codegen_params_t params; jl_codegen_params_t *pparams = (jl_codegen_params_t*)p; @@ -256,8 +256,8 @@ int jl_compile_extern_c(void *llvmmod, void *p, void *sysimg, jl_value_t *declrt if (success && llvmmod == NULL) jl_add_to_ee(std::unique_ptr(into)); } - if (codegen_lock.count == 1 && jl_measure_compile_time[tid]) - jl_cumulative_compile_time[tid] += (jl_hrtime() - compiler_start_time); + if (codegen_lock.count == 1 && measure_compile_time_enabled) + jl_atomic_fetch_add_relaxed(&jl_cumulative_compile_time, (jl_hrtime() - compiler_start_time)); JL_UNLOCK(&codegen_lock); return success; } @@ -313,8 +313,8 @@ jl_code_instance_t *jl_generate_fptr(jl_method_instance_t *mi JL_PROPAGATES_ROOT { JL_LOCK(&codegen_lock); // also disables finalizers, to prevent any unexpected recursion uint64_t compiler_start_time = 0; - int tid = jl_threadid(); - if (jl_measure_compile_time[tid]) + uint8_t measure_compile_time_enabled = jl_atomic_load_relaxed(&jl_measure_compile_time_enabled); + if (measure_compile_time_enabled) compiler_start_time = jl_hrtime(); // if we don't have any decls already, try to generate it now jl_code_info_t *src = NULL; @@ -352,8 +352,8 @@ jl_code_instance_t *jl_generate_fptr(jl_method_instance_t *mi JL_PROPAGATES_ROOT else { codeinst = NULL; } - if (codegen_lock.count == 1 && jl_measure_compile_time[tid]) - jl_cumulative_compile_time[tid] += (jl_hrtime() - compiler_start_time); + if (codegen_lock.count == 1 && measure_compile_time_enabled) + jl_atomic_fetch_add_relaxed(&jl_cumulative_compile_time, (jl_hrtime() - compiler_start_time)); JL_UNLOCK(&codegen_lock); JL_GC_POP(); return codeinst; @@ -367,8 +367,8 @@ void jl_generate_fptr_for_unspecialized(jl_code_instance_t *unspec) } JL_LOCK(&codegen_lock); uint64_t compiler_start_time = 0; - int tid = jl_threadid(); - if (jl_measure_compile_time[tid]) + uint8_t measure_compile_time_enabled = jl_atomic_load_relaxed(&jl_measure_compile_time_enabled); + if (measure_compile_time_enabled) compiler_start_time = jl_hrtime(); if (unspec->invoke == NULL) { jl_code_info_t *src = NULL; @@ -396,8 +396,8 @@ void jl_generate_fptr_for_unspecialized(jl_code_instance_t *unspec) } JL_GC_POP(); } - if (codegen_lock.count == 1 && jl_measure_compile_time[tid]) - jl_cumulative_compile_time[tid] += (jl_hrtime() - compiler_start_time); + if (codegen_lock.count == 1 && measure_compile_time_enabled) + jl_atomic_fetch_add_relaxed(&jl_cumulative_compile_time, (jl_hrtime() - compiler_start_time)); JL_UNLOCK(&codegen_lock); // Might GC } @@ -420,8 +420,8 @@ jl_value_t *jl_dump_method_asm(jl_method_instance_t *mi, size_t world, // so create an exception here so we can print pretty our lies JL_LOCK(&codegen_lock); // also disables finalizers, to prevent any unexpected recursion uint64_t compiler_start_time = 0; - int tid = jl_threadid(); - if (jl_measure_compile_time[tid]) + uint8_t measure_compile_time_enabled = jl_atomic_load_relaxed(&jl_measure_compile_time_enabled); + if (measure_compile_time_enabled) compiler_start_time = jl_hrtime(); specfptr = (uintptr_t)codeinst->specptr.fptr; if (specfptr == 0) { @@ -446,8 +446,8 @@ jl_value_t *jl_dump_method_asm(jl_method_instance_t *mi, size_t world, } JL_GC_POP(); } - if (jl_measure_compile_time[tid]) - jl_cumulative_compile_time[tid] += (jl_hrtime() - compiler_start_time); + if (measure_compile_time_enabled) + jl_atomic_fetch_add_relaxed(&jl_cumulative_compile_time, (jl_hrtime() - compiler_start_time)); JL_UNLOCK(&codegen_lock); } if (specfptr != 0) diff --git a/src/julia_internal.h b/src/julia_internal.h index 8f2f87acca3fed..a7943e11a80675 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -154,8 +154,9 @@ static inline uint64_t cycleclock(void) #include "timing.h" -extern uint8_t *jl_measure_compile_time; -extern uint64_t *jl_cumulative_compile_time; +// Global *atomic* integers controlling *process-wide* measurement of compilation time. +extern uint8_t jl_measure_compile_time_enabled; +extern uint64_t jl_cumulative_compile_time; #ifdef _COMPILER_MICROSOFT_ # define jl_return_address() ((uintptr_t)_ReturnAddress()) diff --git a/src/task.c b/src/task.c index d5ab6258637c6a..88d4eac0863c9a 100644 --- a/src/task.c +++ b/src/task.c @@ -562,7 +562,10 @@ static void JL_NORETURN throw_internal(jl_task_t *ct, jl_value_t *exception JL_M ptls->io_wait = 0; // @time needs its compile timer disabled on error, // and cannot use a try-finally as it would break scope for assignments - jl_measure_compile_time[ptls->tid] = 0; + // We blindly disable compilation time tracking here, for all running Tasks, even though + // it may cause some incorrect measurements. This is a known bug, and is being tracked + // here: https://github.com/JuliaLang/julia/pull/39138 + jl_atomic_store_relaxed(&jl_measure_compile_time_enabled, 0); JL_GC_PUSH1(&exception); jl_gc_unsafe_enter(ptls); if (exception) { diff --git a/src/threading.c b/src/threading.c index 235bb9f870ba19..ffe53c07b45ee3 100644 --- a/src/threading.c +++ b/src/threading.c @@ -287,8 +287,8 @@ void jl_pgcstack_getkey(jl_get_pgcstack_func **f, jl_pgcstack_key_t *k) #endif jl_ptls_t *jl_all_tls_states JL_GLOBALLY_ROOTED; -uint8_t *jl_measure_compile_time = NULL; -uint64_t *jl_cumulative_compile_time = NULL; +uint8_t jl_measure_compile_time_enabled = 0; +uint64_t jl_cumulative_compile_time = 0; // return calling thread's ID // Also update the suspended_threads list in signals-mach when changing the @@ -467,8 +467,6 @@ void jl_init_threading(void) } if (jl_n_threads <= 0) jl_n_threads = 1; - jl_measure_compile_time = (uint8_t*)calloc(jl_n_threads, sizeof(*jl_measure_compile_time)); - jl_cumulative_compile_time = (uint64_t*)calloc(jl_n_threads, sizeof(*jl_cumulative_compile_time)); #ifndef __clang_analyzer__ jl_all_tls_states = (jl_ptls_t*)calloc(jl_n_threads, sizeof(void*)); #endif diff --git a/test/misc.jl b/test/misc.jl index 411135ac633138..94c35c43ffaec5 100644 --- a/test/misc.jl +++ b/test/misc.jl @@ -263,6 +263,22 @@ function timev_macro_scope() end @test timev_macro_scope() == 1 +before = Base.cumulative_compile_time_ns_before(); + +# exercise concurrent calls to `@time` for reentrant compilation time measurement. +t1 = @async @time begin + sleep(2) + @eval module M ; f(x,y) = x+y ; end + @eval M.f(2,3) +end +t2 = @async begin + sleep(1) + @time 2 + 2 +end + +after = Base.cumulative_compile_time_ns_after(); +@test after >= before; + # interactive utilities struct ambigconvert; end # inject a problematic `convert` method to ensure it still works From 7b3ea98321b3a8547661e74afe6b4f7050999d90 Mon Sep 17 00:00:00 2001 From: Dilum Aluthge Date: Mon, 23 Aug 2021 14:29:27 -0400 Subject: [PATCH 098/135] Include the checksums for the SuiteSparse.jl external stdlib in the deps/checksums/suitesparse file (#41967) --- .../md5 | 1 - .../sha512 | 1 - deps/checksums/suitesparse | 2 ++ 3 files changed, 2 insertions(+), 2 deletions(-) delete mode 100644 deps/checksums/SuiteSparse-76856153eef26c008f13520ffa12288e214fe02c.tar.gz/md5 delete mode 100644 deps/checksums/SuiteSparse-76856153eef26c008f13520ffa12288e214fe02c.tar.gz/sha512 diff --git a/deps/checksums/SuiteSparse-76856153eef26c008f13520ffa12288e214fe02c.tar.gz/md5 b/deps/checksums/SuiteSparse-76856153eef26c008f13520ffa12288e214fe02c.tar.gz/md5 deleted file mode 100644 index 16d45f7422a107..00000000000000 --- a/deps/checksums/SuiteSparse-76856153eef26c008f13520ffa12288e214fe02c.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -a7bbe99082964df20037ba70934b2b5a diff --git a/deps/checksums/SuiteSparse-76856153eef26c008f13520ffa12288e214fe02c.tar.gz/sha512 b/deps/checksums/SuiteSparse-76856153eef26c008f13520ffa12288e214fe02c.tar.gz/sha512 deleted file mode 100644 index 88f364d2097c94..00000000000000 --- a/deps/checksums/SuiteSparse-76856153eef26c008f13520ffa12288e214fe02c.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -e22d3bb86fe7952447fe5044307f9e4613ae04eeeb63c5c685d36fa09b78762c76e2ff32bd66dd49cd5c2b8b9b986c79d4e851f76c29ad985f7266c38d795cf1 diff --git a/deps/checksums/suitesparse b/deps/checksums/suitesparse index 25123ba0152945..9971e03dec74ce 100644 --- a/deps/checksums/suitesparse +++ b/deps/checksums/suitesparse @@ -1,5 +1,7 @@ SuiteSparse-5.10.1.tar.gz/md5/68bb912f3cf3d2b01f30ebafef690302 SuiteSparse-5.10.1.tar.gz/sha512/8f85c6d63b76cba95707dfa732c51200df7794cb4c2599dbd92100475747b8d02b05089a47096e85c60b89bc852a8e768e0670f24902a82d29494a80ccf2bb5f +SuiteSparse-76856153eef26c008f13520ffa12288e214fe02c.tar.gz/md5/a7bbe99082964df20037ba70934b2b5a +SuiteSparse-76856153eef26c008f13520ffa12288e214fe02c.tar.gz/sha512/e22d3bb86fe7952447fe5044307f9e4613ae04eeeb63c5c685d36fa09b78762c76e2ff32bd66dd49cd5c2b8b9b986c79d4e851f76c29ad985f7266c38d795cf1 SuiteSparse.v5.10.1+0.aarch64-apple-darwin.tar.gz/md5/b9392f8e71c0c40d37489e7b2071c5ad SuiteSparse.v5.10.1+0.aarch64-apple-darwin.tar.gz/sha512/109d67cb009e3b2931b94d63cbdaaee29d60dc190b731ebe3737181cd48d913b8a1333043c67be8179c73e4d3ae32ed1361ab4e34312c0f42e4b29f8a7afda3e SuiteSparse.v5.10.1+0.aarch64-linux-gnu.tar.gz/md5/1b2651ede4a74cd57f65505a65093314 From 0974dfa1bd2779cdd07283359236c5aa4b8536da Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Mon, 23 Aug 2021 14:29:01 -0500 Subject: [PATCH 099/135] Validate CodeInstances with no external edges (#41961) In #38983 and #41872, it was discovered that only CodeInstances with external backedges get validated after deserialization. This adds a "second chance" for each CodeInstance: it validates any that have neither been validated nor invalidated by the end of deserialization. Closes #41872 --- src/dump.c | 26 +++++++++++++++++++++++++- test/precompile.jl | 28 ++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/src/dump.c b/src/dump.c index 8c9d68f51834be..af3290a5114eb0 100644 --- a/src/dump.c +++ b/src/dump.c @@ -46,6 +46,7 @@ static jl_value_t *deser_symbols[256]; static htable_t backref_table; static int backref_table_numel; static arraylist_t backref_list; +static htable_t new_code_instance_validate; // list of (jl_value_t **loc, size_t pos) entries // for anything that was flagged by the deserializer for later @@ -1616,8 +1617,10 @@ static jl_value_t *jl_deserialize_value_code_instance(jl_serializer_state *s, jl codeinst->precompile = 1; codeinst->next = (jl_code_instance_t*)jl_deserialize_value(s, (jl_value_t**)&codeinst->next); jl_gc_wb(codeinst, codeinst->next); - if (validate) + if (validate) { codeinst->min_world = jl_world_counter; + ptrhash_put(&new_code_instance_validate, codeinst, (void*)(~(uintptr_t)HT_NOTFOUND)); // "HT_FOUND" + } return (jl_value_t*)codeinst; } @@ -2055,10 +2058,16 @@ static void jl_insert_backedges(jl_array_t *list, jl_array_t *targets) while (codeinst) { if (codeinst->min_world > 0) codeinst->max_world = ~(size_t)0; + ptrhash_put(&new_code_instance_validate, codeinst, HT_NOTFOUND); // mark it as handled codeinst = jl_atomic_load_relaxed(&codeinst->next); } } else { + jl_code_instance_t *codeinst = caller->cache; + while (codeinst) { + ptrhash_put(&new_code_instance_validate, codeinst, HT_NOTFOUND); // should be left invalid + codeinst = jl_atomic_load_relaxed(&codeinst->next); + } if (_jl_debug_method_invalidation) { jl_array_ptr_1d_push(_jl_debug_method_invalidation, (jl_value_t*)caller); loctag = jl_cstr_to_string("insert_backedges"); @@ -2069,6 +2078,16 @@ static void jl_insert_backedges(jl_array_t *list, jl_array_t *targets) JL_GC_POP(); } +static void validate_new_code_instances(void) +{ + size_t i; + for (i = 0; i < new_code_instance_validate.size; i += 2) { + if (new_code_instance_validate.table[i+1] != HT_NOTFOUND) { + ((jl_code_instance_t*)new_code_instance_validate.table[i])->max_world = ~(size_t)0; + new_code_instance_validate.table[i+1] = HT_NOTFOUND; + } + } +} static jl_value_t *read_verify_mod_list(ios_t *s, jl_array_t *mod_list) { @@ -2636,6 +2655,7 @@ static jl_value_t *_jl_restore_incremental(ios_t *f, jl_array_t *mod_array) arraylist_new(&backref_list, 4000); arraylist_push(&backref_list, jl_main_module); arraylist_new(&flagref_list, 0); + htable_new(&new_code_instance_validate, 0); arraylist_new(&ccallable_list, 0); htable_new(&uniquing_table, 0); @@ -2671,7 +2691,11 @@ static jl_value_t *_jl_restore_incremental(ios_t *f, jl_array_t *mod_array) jl_insert_backedges((jl_array_t*)external_backedges, (jl_array_t*)external_edges); // restore external backedges (needs to be last) + // check new CodeInstances and validate any that lack external backedges + validate_new_code_instances(); + serializer_worklist = NULL; + htable_free(&new_code_instance_validate); arraylist_free(&flagref_list); arraylist_free(&backref_list); ios_close(f); diff --git a/test/precompile.jl b/test/precompile.jl index 49f754186c50f1..999bd07c9e12b6 100644 --- a/test/precompile.jl +++ b/test/precompile.jl @@ -876,6 +876,34 @@ precompile_test_harness("Renamed Imports") do load_path @test (@eval (using RenameImports; RenameImports.test())) isa Module end +# issue #41872 (example from #38983) +precompile_test_harness("No external edges") do load_path + write(joinpath(load_path, "NoExternalEdges.jl"), + """ + module NoExternalEdges + bar(x::Int) = hcat(rand()) + @inline bar() = hcat(rand()) + bar(x::Float64) = bar() + foo1() = bar(1) + foo2() = bar(1.0) + foo3() = bar() + foo4() = hcat(rand()) + precompile(foo1, ()) + precompile(foo2, ()) + precompile(foo3, ()) + precompile(foo4, ()) + end + """) + Base.compilecache(Base.PkgId("NoExternalEdges")) + @eval begin + using NoExternalEdges + @test only(methods(NoExternalEdges.foo1)).specializations[1].cache.max_world != 0 + @test only(methods(NoExternalEdges.foo2)).specializations[1].cache.max_world != 0 + @test only(methods(NoExternalEdges.foo3)).specializations[1].cache.max_world != 0 + @test only(methods(NoExternalEdges.foo4)).specializations[1].cache.max_world != 0 + end +end + @testset "issue 38149" begin M = Module() @eval M begin From c88db4e32a8807861825a31cfe176d5ffad058b1 Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Mon, 23 Aug 2021 14:46:34 -0500 Subject: [PATCH 100/135] Signatures: restrict color to backtrace printing (#41929) Fixes #41928 --- base/show.jl | 4 +++- test/show.jl | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/base/show.jl b/base/show.jl index 40fe1ec7d64f04..f3110d59814295 100644 --- a/base/show.jl +++ b/base/show.jl @@ -2378,7 +2378,9 @@ end function print_type_stacktrace(io, type; color=:normal) str = sprint(show, type, context=io) i = findfirst('{', str) - if i === nothing || !get(io, :backtrace, false)::Bool + if !get(io, :backtrace, false)::Bool + print(io, str) + elseif i === nothing printstyled(io, str; color=color) else printstyled(io, str[1:prevind(str,i)]; color=color) diff --git a/test/show.jl b/test/show.jl index cb9e2e9fc3b8fc..f9c3eb1545b3e0 100644 --- a/test/show.jl +++ b/test/show.jl @@ -1377,6 +1377,11 @@ let m = which(T20332{Int}(), (Int,)), mi = Core.Compiler.specialize_method(m, Tuple{T20332{T}, Int} where T, Core.svec()) # test that this doesn't throw an error @test occursin("MethodInstance for", repr(mi)) + # issue #41928 + str = sprint(mi; context=:color=>true) do io, mi + printstyled(io, mi; color=:light_cyan) + end + @test !occursin("\U1b[0m", str) end @test sprint(show, Main) == "Main" From 292f1a95e723c1a72011e525e050eaa971ee0085 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Mon, 23 Aug 2021 16:33:14 -0400 Subject: [PATCH 101/135] types: fix cache computation (#41935) Need to compute `cacheable` after normalization, since the purpose of the normalization was to turn these into normal cacheable objects, when applicable. Brokenness exposed by #36211 Fixes #41503 --- src/jltypes.c | 68 +++++++++++++++++++++++---------------------------- test/core.jl | 7 ++++++ 2 files changed, 37 insertions(+), 38 deletions(-) diff --git a/src/jltypes.c b/src/jltypes.c index aacd2ba19ccca4..f85c75a4a2d201 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -897,19 +897,19 @@ struct _jl_typestack_t; typedef struct _jl_typestack_t jl_typestack_t; static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value_t **iparams, size_t ntp, - int cacheable, jl_typestack_t *stack, jl_typeenv_t *env); + jl_typestack_t *stack, jl_typeenv_t *env); // Build an environment mapping a TypeName's parameters to parameter values. // This is the environment needed for instantiating a type's supertype and field types. static jl_value_t *inst_datatype_env(jl_value_t *dt, jl_svec_t *p, jl_value_t **iparams, size_t ntp, - int cacheable, jl_typestack_t *stack, jl_typeenv_t *env, int c) + jl_typestack_t *stack, jl_typeenv_t *env, int c) { if (jl_is_datatype(dt)) - return inst_datatype_inner((jl_datatype_t*)dt, p, iparams, ntp, cacheable, stack, env); + return inst_datatype_inner((jl_datatype_t*)dt, p, iparams, ntp, stack, env); assert(jl_is_unionall(dt)); jl_unionall_t *ua = (jl_unionall_t*)dt; jl_typeenv_t e = { ua->var, iparams[c], env }; - return inst_datatype_env(ua->body, p, iparams, ntp, cacheable, stack, &e, c + 1); + return inst_datatype_env(ua->body, p, iparams, ntp, stack, &e, c + 1); } jl_value_t *jl_apply_type(jl_value_t *tc, jl_value_t **params, size_t n) @@ -925,14 +925,7 @@ jl_value_t *jl_apply_type(jl_value_t *tc, jl_value_t **params, size_t n) jl_value_t *u = jl_unwrap_unionall(tc); if (jl_is_datatype(u) && n == jl_nparams((jl_datatype_t*)u) && ((jl_datatype_t*)u)->name->wrapper == tc) { - int cacheable = 1; - for (i = 0; i < n; i++) { - if (jl_has_free_typevars(params[i])) { - cacheable = 0; - break; - } - } - return inst_datatype_env(tc, NULL, params, n, cacheable, NULL, NULL, 0); + return inst_datatype_env(tc, NULL, params, n, NULL, NULL, 0); } } JL_GC_PUSH1(&tc); @@ -1002,8 +995,8 @@ jl_datatype_t *jl_apply_cmpswap_type(jl_value_t *dt) jl_value_t *params[2]; jl_value_t *names = jl_atomic_load_relaxed(&cmpswap_names); if (names == NULL) { - params[0] = jl_symbol("old"); - params[1] = jl_symbol("success"); + params[0] = (jl_value_t*)jl_symbol("old"); + params[1] = (jl_value_t*)jl_symbol("success"); jl_value_t *lnames = jl_f_tuple(NULL, params, 2); if (jl_atomic_cmpswap(&cmpswap_names, &names, lnames)) names = jl_atomic_load_relaxed(&cmpswap_names); // == lnames @@ -1012,7 +1005,7 @@ jl_datatype_t *jl_apply_cmpswap_type(jl_value_t *dt) params[1] = (jl_value_t*)jl_bool_type; jl_datatype_t *tuptyp = jl_apply_tuple_type_v(params, 2); JL_GC_PROMISE_ROOTED(tuptyp); // (JL_ALWAYS_LEAFTYPE) - jl_datatype_t *rettyp = (jl_datatype_t*)jl_apply_type2(jl_namedtuple_type, names, tuptyp); + jl_datatype_t *rettyp = (jl_datatype_t*)jl_apply_type2((jl_value_t*)jl_namedtuple_type, names, (jl_value_t*)tuptyp); JL_GC_PROMISE_ROOTED(rettyp); // (JL_ALWAYS_LEAFTYPE) return rettyp; } @@ -1343,18 +1336,32 @@ jl_value_t *normalize_unionalls(jl_value_t *t) static jl_value_t *_jl_instantiate_type_in_env(jl_value_t *ty, jl_unionall_t *env, jl_value_t **vals, jl_typeenv_t *prev, jl_typestack_t *stack); static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value_t **iparams, size_t ntp, - int cacheable, jl_typestack_t *stack, jl_typeenv_t *env) + jl_typestack_t *stack, jl_typeenv_t *env) { jl_typestack_t top; jl_typename_t *tn = dt->name; int istuple = (tn == jl_tuple_typename); int isnamedtuple = (tn == jl_namedtuple_typename); if (dt->name != jl_type_typename) { - for (size_t i = 0; i < ntp; i++) + size_t i; + for (i = 0; i < ntp; i++) iparams[i] = normalize_unionalls(iparams[i]); } - // check type cache + // check type cache, if applicable + int cacheable = 1; + if (istuple) { + size_t i; + for (i = 0; cacheable && i < ntp; i++) + if (!jl_is_concrete_type(iparams[i]) && iparams[i] != jl_bottom_type) + cacheable = 0; + } + else { + size_t i; + for (i = 0; cacheable && i < ntp; i++) + if (jl_has_free_typevars(iparams[i])) + cacheable = 0; + } if (cacheable) { size_t i; for (i = 0; i < ntp; i++) { @@ -1553,13 +1560,7 @@ static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value static jl_tupletype_t *jl_apply_tuple_type_v_(jl_value_t **p, size_t np, jl_svec_t *params) { - int cacheable = 1; - for (size_t i = 0; i < np; i++) { - assert(p[i]); - if (!jl_is_concrete_type(p[i]) && p[i] != jl_bottom_type) - cacheable = 0; - } - return (jl_datatype_t*)inst_datatype_inner(jl_anytuple_type, params, p, np, cacheable, NULL, NULL); + return (jl_datatype_t*)inst_datatype_inner(jl_anytuple_type, params, p, np, NULL, NULL); } JL_DLLEXPORT jl_tupletype_t *jl_apply_tuple_type(jl_svec_t *params) @@ -1581,7 +1582,6 @@ jl_tupletype_t *jl_inst_arg_tuple_type(jl_value_t *arg1, jl_value_t **args, size { jl_tupletype_t *tt = (jl_datatype_t*)lookup_typevalue(jl_tuple_typename, arg1, args, nargs, leaf); if (tt == NULL) { - int cacheable = 1; size_t i; jl_svec_t *params = jl_alloc_svec(nargs); JL_GC_PUSH1(¶ms); @@ -1593,14 +1593,13 @@ jl_tupletype_t *jl_inst_arg_tuple_type(jl_value_t *arg1, jl_value_t **args, size // `jl_typeof(ai)`, but that will require some redesign of the caching // logic. ai = (jl_value_t*)jl_wrap_Type(ai); - cacheable = 0; } else { ai = jl_typeof(ai); } jl_svecset(params, i, ai); } - tt = (jl_datatype_t*)inst_datatype_inner(jl_anytuple_type, params, jl_svec_data(params), nargs, cacheable, NULL, NULL); + tt = (jl_datatype_t*)inst_datatype_inner(jl_anytuple_type, params, jl_svec_data(params), nargs, NULL, NULL); JL_GC_POP(); } return tt; @@ -1668,9 +1667,6 @@ static jl_value_t *inst_tuple_w_(jl_value_t *t, jl_typeenv_t *env, jl_typestack_ iparams = jl_svec_data(ip_heap); } int bound = 0; - int cacheable = 1; - if (jl_is_va_tuple(tt)) - cacheable = 0; int i; for (i = 0; i < ntp; i++) { jl_value_t *elt = jl_svecref(tp, i); @@ -1679,11 +1675,9 @@ static jl_value_t *inst_tuple_w_(jl_value_t *t, jl_typeenv_t *env, jl_typestack_ if (ip_heap) jl_gc_wb(ip_heap, pi); bound |= (pi != elt); - if (cacheable && !jl_is_concrete_type(pi)) - cacheable = 0; } if (bound) - t = inst_datatype_inner(tt, ip_heap, iparams, ntp, cacheable, stack, env); + t = inst_datatype_inner(tt, ip_heap, iparams, ntp, stack, env); JL_GC_POP(); return t; } @@ -1770,18 +1764,16 @@ static jl_value_t *inst_type_w_(jl_value_t *t, jl_typeenv_t *env, jl_typestack_t size_t ntp = jl_svec_len(tp); jl_value_t **iparams; JL_GC_PUSHARGS(iparams, ntp); - int cacheable = 1, bound = 0; + int bound = 0; for (i = 0; i < ntp; i++) { jl_value_t *elt = jl_svecref(tp, i); jl_value_t *pi = inst_type_w_(elt, env, stack, check); iparams[i] = pi; bound |= (pi != elt); - if (cacheable && jl_has_free_typevars(pi)) - cacheable = 0; } // if t's parameters are not bound in the environment, return it uncopied (#9378) if (bound) - t = inst_datatype_inner(tt, NULL, iparams, ntp, cacheable, stack, env); + t = inst_datatype_inner(tt, NULL, iparams, ntp, stack, env); JL_GC_POP(); return t; } diff --git a/test/core.jl b/test/core.jl index a9c9f6222cd9f0..d9697266530465 100644 --- a/test/core.jl +++ b/test/core.jl @@ -7579,3 +7579,10 @@ const T35130 = Tuple{Vector{Int}, <:Any} end h35130(x) = A35130(Any[x][1]::Vector{T35130}) @test h35130(T35130[([1],1)]) isa A35130 + +# issue #41503 +let S = Tuple{Tuple{Tuple{K, UInt128} where K<:Tuple{Int64}, Int64}}, + T = Tuple{Tuple{Tuple{Tuple{Int64}, UInt128}, Int64}} + @test pointer_from_objref(T) === pointer_from_objref(S) + @test isbitstype(T) +end From cdd2f30d445756377ed154450384461ebc3f3a9c Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Tue, 24 Aug 2021 13:21:29 +0900 Subject: [PATCH 102/135] inference: `prioritize force_constant_prop` over `const_prop_entry_heuristic` (#41882) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently our constant-prop' heuristics work in the following way: 1. `const_prop_entry_heuristic` 2. `const_prop_argument_heuristic` & `const_prop_rettype_heuristic` 3. `force_const_prop` custom heuristic & `!const_prop_function_heuristic` 4. `MethodInstance` specialization and `const_prop_methodinstance_heuristic` This PR changes it so that the step 1. now works like: 1. `force_const_prop` custom heuristic & `const_prop_entry_heuristic` and the steps 2., 3. and 4. don't change This change particularly allows us to more forcibly constant-propagate for `getproperty` and `setproperty!`, and inline them more, e.g.: ```julia # if we don't force constant-prop', `T = fieldtype(Foo, ::Symbol)` will be union-split to # `Union{Type{Any},Type{Int}` and it will make `convert(T, nothing)` too costly # and it leads to inlining failure mutable struct Foo val _::Int end function setter(xs) for x in xs x.val = nothing # `setproperty!` can be inlined with this PR end end ``` It might be useful because now we can intervene into the constant-prop' heuristic in a more reliable way with the `aggressive_constprop` interface. I did the simple benchmark below, and it looks like this change doesn't cause the latency problem for this particular example: ```zsh ~/julia master aviatesk@amdci2 6s ❯ ./usr/bin/julia -e '@time using Plots; @time plot(rand(10,3))' 3.708500 seconds (7.28 M allocations: 506.128 MiB, 3.45% gc time, 1.13% compilation time) 2.817794 seconds (3.45 M allocations: 195.127 MiB, 7.84% gc time, 53.76% compilation time) ~/julia avi/forceconstantprop aviatesk@amdci2 6s ❯ ./usr/bin/julia -e '@time using Plots; @time plot(rand(10,3))' 3.622109 seconds (7.02 M allocations: 481.710 MiB, 4.19% gc time, 1.17% compilation time) 2.863419 seconds (3.44 M allocations: 194.210 MiB, 8.02% gc time, 53.53% compilation time) ``` --- base/compiler/abstractinterpretation.jl | 19 +++++++++++++------ test/compiler/inline.jl | 23 +++++++++++++++++++++++ 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index efcebf8c1408e7..4af4eb672bb6dd 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -567,16 +567,21 @@ end function maybe_get_const_prop_profitable(interp::AbstractInterpreter, result::MethodCallResult, @nospecialize(f), argtypes::Vector{Any}, match::MethodMatch, sv::InferenceState) - const_prop_entry_heuristic(interp, result, sv) || return nothing + if !InferenceParams(interp).ipo_constant_propagation + add_remark!(interp, sv, "[constprop] Disabled by parameter") + return nothing + end method = match.method + force = force_const_prop(interp, f, method) + force || const_prop_entry_heuristic(interp, result, sv) || return nothing nargs::Int = method.nargs method.isva && (nargs -= 1) - if length(argtypes) < nargs + length(argtypes) < nargs && return nothing + if !(const_prop_argument_heuristic(interp, argtypes) || const_prop_rettype_heuristic(interp, result.rt)) + add_remark!(interp, sv, "[constprop] Disabled by argument and rettype heuristics") return nothing end - const_prop_argument_heuristic(interp, argtypes) || const_prop_rettype_heuristic(interp, result.rt) || return nothing allconst = is_allconst(argtypes) - force = force_const_prop(interp, f, method) if !force if !const_prop_function_heuristic(interp, f, argtypes, nargs, allconst) add_remark!(interp, sv, "[constprop] Disabled by function heuristic") @@ -599,10 +604,12 @@ end function const_prop_entry_heuristic(interp::AbstractInterpreter, result::MethodCallResult, sv::InferenceState) if call_result_unused(sv) && result.edgecycle - add_remark!(interp, sv, "[constprop] Edgecycle with unused result") + add_remark!(interp, sv, "[constprop] Disabled by entry heuristic (edgecycle with unused result)") return false end - return is_improvable(result.rt) && InferenceParams(interp).ipo_constant_propagation + is_improvable(result.rt) && return true + add_remark!(interp, sv, "[constprop] Disabled by entry heuristic (unimprovable return type)") + return false end # see if propagating constants may be worthwhile diff --git a/test/compiler/inline.jl b/test/compiler/inline.jl index 00797304ce5c0b..9358dce3325f75 100644 --- a/test/compiler/inline.jl +++ b/test/compiler/inline.jl @@ -498,6 +498,29 @@ end end end +# force constant-prop' for `setproperty!` +let m = Module() + ci = @eval m begin + # if we don't force constant-prop', `T = fieldtype(Foo, ::Symbol)` will be union-split to + # `Union{Type{Any},Type{Int}` and it will make `convert(T, nothing)` too costly + # and it leads to inlining failure + mutable struct Foo + val + _::Int + end + + function setter(xs) + for x in xs + x.val = nothing + end + end + + $code_typed1(setter, (Vector{Foo},)) + end + + @test !any(x->isinvoke(x, :setproperty!), ci.code) +end + # Issue #41299 - inlining deletes error check in :> g41299(f::Tf, args::Vararg{Any,N}) where {Tf,N} = f(args...) @test_throws TypeError g41299(>:, 1, 2) From 5451c7de75716b81a72881b4cabcbe0c7a10f515 Mon Sep 17 00:00:00 2001 From: Felipe Noronha Date: Tue, 24 Aug 2021 07:41:33 -0300 Subject: [PATCH 103/135] avoid vector allocation when PartitionIterator is cut short (#41950) --- base/iterators.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/iterators.jl b/base/iterators.jl index f9728cbbd07935..c0a68a36d836e2 100644 --- a/base/iterators.jl +++ b/base/iterators.jl @@ -1191,11 +1191,11 @@ end struct IterationCutShort; end function iterate(itr::PartitionIterator, state...) - v = Vector{eltype(itr.c)}(undef, itr.n) # This is necessary to remember whether we cut the # last element short. In such cases, we do return that # element, but not the next one state === (IterationCutShort(),) && return nothing + v = Vector{eltype(itr.c)}(undef, itr.n) i = 0 y = iterate(itr.c, state...) while y !== nothing From 3d058b205ed6a78f1643642859c1add1954de227 Mon Sep 17 00:00:00 2001 From: DilumAluthgeBot <43731525+DilumAluthgeBot@users.noreply.github.com> Date: Tue, 24 Aug 2021 12:35:45 +0000 Subject: [PATCH 104/135] =?UTF-8?q?=F0=9F=A4=96=20Bump=20the=20SuiteSparse?= =?UTF-8?q?=20stdlib=20from=207685615=20to=20b15c39b=20(#41980)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Dilum Aluthge --- deps/checksums/suitesparse | 4 ++-- stdlib/SuiteSparse.version | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/deps/checksums/suitesparse b/deps/checksums/suitesparse index 9971e03dec74ce..b34ee2a852f0ee 100644 --- a/deps/checksums/suitesparse +++ b/deps/checksums/suitesparse @@ -1,7 +1,7 @@ SuiteSparse-5.10.1.tar.gz/md5/68bb912f3cf3d2b01f30ebafef690302 SuiteSparse-5.10.1.tar.gz/sha512/8f85c6d63b76cba95707dfa732c51200df7794cb4c2599dbd92100475747b8d02b05089a47096e85c60b89bc852a8e768e0670f24902a82d29494a80ccf2bb5f -SuiteSparse-76856153eef26c008f13520ffa12288e214fe02c.tar.gz/md5/a7bbe99082964df20037ba70934b2b5a -SuiteSparse-76856153eef26c008f13520ffa12288e214fe02c.tar.gz/sha512/e22d3bb86fe7952447fe5044307f9e4613ae04eeeb63c5c685d36fa09b78762c76e2ff32bd66dd49cd5c2b8b9b986c79d4e851f76c29ad985f7266c38d795cf1 +SuiteSparse-b15c39be53f7823c721c1f8a7c036105e2baa04a.tar.gz/md5/412d21908e1d00de43c158b372025430 +SuiteSparse-b15c39be53f7823c721c1f8a7c036105e2baa04a.tar.gz/sha512/c2cbb59daeee6493ccf741fbc1baad92f444f0f2320e84a102c7fec8fc30532acb5a295edd19dfa662f63d14b2bdaadbec5f81e64d946fc35ffb1dd6ffd80abc SuiteSparse.v5.10.1+0.aarch64-apple-darwin.tar.gz/md5/b9392f8e71c0c40d37489e7b2071c5ad SuiteSparse.v5.10.1+0.aarch64-apple-darwin.tar.gz/sha512/109d67cb009e3b2931b94d63cbdaaee29d60dc190b731ebe3737181cd48d913b8a1333043c67be8179c73e4d3ae32ed1361ab4e34312c0f42e4b29f8a7afda3e SuiteSparse.v5.10.1+0.aarch64-linux-gnu.tar.gz/md5/1b2651ede4a74cd57f65505a65093314 diff --git a/stdlib/SuiteSparse.version b/stdlib/SuiteSparse.version index b9f2f184893cd8..e2700363ad665a 100644 --- a/stdlib/SuiteSparse.version +++ b/stdlib/SuiteSparse.version @@ -1,2 +1,2 @@ SUITESPARSE_BRANCH = master -SUITESPARSE_SHA1 = 76856153eef26c008f13520ffa12288e214fe02c +SUITESPARSE_SHA1 = b15c39be53f7823c721c1f8a7c036105e2baa04a From 92c84bf3865403355af463b5a1dee42bf7143592 Mon Sep 17 00:00:00 2001 From: Simeon Schaub Date: Tue, 24 Aug 2021 20:19:34 +0200 Subject: [PATCH 105/135] fix #25678: return matters for generated functions (#40778) Just explicitely check for `CodeInfo` objects and use an explicit `return` in this case inside the `@generated` macro. Co-authored-by: Jeff Bezanson --- base/expr.jl | 5 ++++- test/syntax.jl | 7 +++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/base/expr.jl b/base/expr.jl index 86d77fc1e4f88f..b91181ea2dfe7e 100644 --- a/base/expr.jl +++ b/base/expr.jl @@ -464,7 +464,10 @@ macro generated(f) Expr(:block, lno, Expr(:if, Expr(:generated), - body, + # https://github.com/JuliaLang/julia/issues/25678 + Expr(:block, + :(local tmp = $body), + :(if tmp isa Core.CodeInfo; return tmp; else tmp; end)), Expr(:block, Expr(:meta, :generated_only), Expr(:return, nothing)))))) diff --git a/test/syntax.jl b/test/syntax.jl index 95242b44b4871f..9b31c0b874fbdf 100644 --- a/test/syntax.jl +++ b/test/syntax.jl @@ -2959,3 +2959,10 @@ end ex.args = fill!(Vector{Any}(undef, 600000), 1) @test_throws ErrorException("syntax: expression too large") eval(ex) end + +# issue 25678 +@generated f25678(x::T) where {T} = code_lowered(sin, Tuple{x})[] +@test f25678(pi/6) === sin(pi/6) + +@generated g25678(x) = return :x +@test g25678(7) === 7 From 7da505b5420cfd402787bbca4bae0da793ff0501 Mon Sep 17 00:00:00 2001 From: Elliot Saba Date: Tue, 24 Aug 2021 18:30:28 +0000 Subject: [PATCH 106/135] Revert "add stack-probes to make stack-overflow detection more reliable (#40068)" This reverts commit c0f8aef3bfcf59699ee0f4db46f183fcd8dde0c1. --- src/codegen.cpp | 35 ++++++++++++++++++++--------------- test/llvmpasses/noinline.jl | 2 +- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index 744d29629b0cae..7742bdc6c8039a 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -1777,14 +1777,6 @@ static void jl_init_function(Function *F) #ifdef JL_DISABLE_FPO F->addFnAttr("frame-pointer", "all"); #endif -#if !defined(_COMPILER_ASAN_ENABLED_) && !defined(_OS_WINDOWS_) - // ASAN won't like us accessing undefined memory causing spurious issues, - // and Windows has platform-specific handling which causes it to mishandle - // this annotation. Other platforms should just ignore this if they don't - // implement it. - F->addFnAttr("probe-stack", "inline-asm"); - //F->addFnAttr("stack-probe-size", 4096); // can use this to change the default -#endif } static std::pair uses_specsig(jl_method_instance_t *lam, jl_value_t *rettype, bool prefer_specsig) @@ -6496,7 +6488,20 @@ static std::pair, jl_llvm_functions_t> } } - // step 6. set up GC frame + /* + // step 6. (optional) check for stack overflow (the slower way) + Value *cur_sp = + ctx.builder.CreateCall(Intrinsic::getDeclaration(M, + Intrinsic::frameaddress), + ConstantInt::get(T_int32, 0)); + Value *sp_ok = + ctx.builder.CreateICmpUGT(cur_sp, + ConstantInt::get(T_size, + (uptrint_t)jl_stack_lo)); + error_unless(ctx, sp_ok, "stack overflow"); + */ + + // step 7. set up GC frame allocate_gc_frame(ctx, b0); Value *last_age = NULL; emit_last_age_field(ctx); @@ -6504,7 +6509,7 @@ static std::pair, jl_llvm_functions_t> last_age = tbaa_decorate(tbaa_gcframe, ctx.builder.CreateAlignedLoad(ctx.world_age_field, Align(sizeof(size_t)))); } - // step 7. allocate local variables slots + // step 8. allocate local variables slots // must be in the first basic block for the llvm mem2reg pass to work auto allocate_local = [&](jl_varinfo_t &varinfo, jl_sym_t *s) { jl_value_t *jt = varinfo.value.typ; @@ -6622,7 +6627,7 @@ static std::pair, jl_llvm_functions_t> } } - // step 8. move args into local variables + // step 9. move args into local variables Function::arg_iterator AI = f->arg_begin(); auto get_specsig_arg = [&](jl_value_t *argType, Type *llvmArgType, bool isboxed) { @@ -6752,7 +6757,7 @@ static std::pair, jl_llvm_functions_t> } } - // step 9. allocate rest argument + // step 10. allocate rest argument CallInst *restTuple = NULL; if (va && ctx.vaSlot != -1) { jl_varinfo_t &vi = ctx.slots[ctx.vaSlot]; @@ -6794,7 +6799,7 @@ static std::pair, jl_llvm_functions_t> } } - // step 10. Compute properties for each statements + // step 11. Compute properties for each statements // This needs to be computed by iterating in the IR order // instead of control flow order. auto in_user_mod = [] (jl_module_t *mod) { @@ -6916,7 +6921,7 @@ static std::pair, jl_llvm_functions_t> Instruction &prologue_end = ctx.builder.GetInsertBlock()->back(); - // step 11. Do codegen in control flow order + // step 12. Do codegen in control flow order std::vector workstack; std::map BB; std::map come_from_bb; @@ -7463,7 +7468,7 @@ static std::pair, jl_llvm_functions_t> PN->eraseFromParent(); } - // step 12. Perform any delayed instantiations + // step 13. Perform any delayed instantiations if (ctx.debug_enabled) { bool in_prologue = true; for (auto &BB : *ctx.f) { diff --git a/test/llvmpasses/noinline.jl b/test/llvmpasses/noinline.jl index c4aa22bf80a71b..f542968b219794 100644 --- a/test/llvmpasses/noinline.jl +++ b/test/llvmpasses/noinline.jl @@ -17,5 +17,5 @@ include(joinpath("..", "testhelpers", "llvmpasses.jl")) return A + B end -# CHECK: attributes #{{[0-9]+}} = {{{[^}]*}} noinline {{[^}]*}}} +# CHECK: attributes #{{[0-9]+}} = {{{([a-z]+ )*}} noinline {{([a-z]+ )*}}} emit(simple_noinline, Float64, Float64) From 24e0831d068b50d605cc8b1400c642cfc5739d0c Mon Sep 17 00:00:00 2001 From: Elliot Saba Date: Tue, 24 Aug 2021 18:32:50 +0000 Subject: [PATCH 107/135] Revert "Revert "add stack-probes to make stack-overflow detection more reliable (#40068)"" This reverts commit 7da505b5420cfd402787bbca4bae0da793ff0501. Elliot didn't `git worktree` right, and ended up commiting to `master` isntead of a feature branch --- src/codegen.cpp | 35 +++++++++++++++-------------------- test/llvmpasses/noinline.jl | 2 +- 2 files changed, 16 insertions(+), 21 deletions(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index 7742bdc6c8039a..744d29629b0cae 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -1777,6 +1777,14 @@ static void jl_init_function(Function *F) #ifdef JL_DISABLE_FPO F->addFnAttr("frame-pointer", "all"); #endif +#if !defined(_COMPILER_ASAN_ENABLED_) && !defined(_OS_WINDOWS_) + // ASAN won't like us accessing undefined memory causing spurious issues, + // and Windows has platform-specific handling which causes it to mishandle + // this annotation. Other platforms should just ignore this if they don't + // implement it. + F->addFnAttr("probe-stack", "inline-asm"); + //F->addFnAttr("stack-probe-size", 4096); // can use this to change the default +#endif } static std::pair uses_specsig(jl_method_instance_t *lam, jl_value_t *rettype, bool prefer_specsig) @@ -6488,20 +6496,7 @@ static std::pair, jl_llvm_functions_t> } } - /* - // step 6. (optional) check for stack overflow (the slower way) - Value *cur_sp = - ctx.builder.CreateCall(Intrinsic::getDeclaration(M, - Intrinsic::frameaddress), - ConstantInt::get(T_int32, 0)); - Value *sp_ok = - ctx.builder.CreateICmpUGT(cur_sp, - ConstantInt::get(T_size, - (uptrint_t)jl_stack_lo)); - error_unless(ctx, sp_ok, "stack overflow"); - */ - - // step 7. set up GC frame + // step 6. set up GC frame allocate_gc_frame(ctx, b0); Value *last_age = NULL; emit_last_age_field(ctx); @@ -6509,7 +6504,7 @@ static std::pair, jl_llvm_functions_t> last_age = tbaa_decorate(tbaa_gcframe, ctx.builder.CreateAlignedLoad(ctx.world_age_field, Align(sizeof(size_t)))); } - // step 8. allocate local variables slots + // step 7. allocate local variables slots // must be in the first basic block for the llvm mem2reg pass to work auto allocate_local = [&](jl_varinfo_t &varinfo, jl_sym_t *s) { jl_value_t *jt = varinfo.value.typ; @@ -6627,7 +6622,7 @@ static std::pair, jl_llvm_functions_t> } } - // step 9. move args into local variables + // step 8. move args into local variables Function::arg_iterator AI = f->arg_begin(); auto get_specsig_arg = [&](jl_value_t *argType, Type *llvmArgType, bool isboxed) { @@ -6757,7 +6752,7 @@ static std::pair, jl_llvm_functions_t> } } - // step 10. allocate rest argument + // step 9. allocate rest argument CallInst *restTuple = NULL; if (va && ctx.vaSlot != -1) { jl_varinfo_t &vi = ctx.slots[ctx.vaSlot]; @@ -6799,7 +6794,7 @@ static std::pair, jl_llvm_functions_t> } } - // step 11. Compute properties for each statements + // step 10. Compute properties for each statements // This needs to be computed by iterating in the IR order // instead of control flow order. auto in_user_mod = [] (jl_module_t *mod) { @@ -6921,7 +6916,7 @@ static std::pair, jl_llvm_functions_t> Instruction &prologue_end = ctx.builder.GetInsertBlock()->back(); - // step 12. Do codegen in control flow order + // step 11. Do codegen in control flow order std::vector workstack; std::map BB; std::map come_from_bb; @@ -7468,7 +7463,7 @@ static std::pair, jl_llvm_functions_t> PN->eraseFromParent(); } - // step 13. Perform any delayed instantiations + // step 12. Perform any delayed instantiations if (ctx.debug_enabled) { bool in_prologue = true; for (auto &BB : *ctx.f) { diff --git a/test/llvmpasses/noinline.jl b/test/llvmpasses/noinline.jl index f542968b219794..c4aa22bf80a71b 100644 --- a/test/llvmpasses/noinline.jl +++ b/test/llvmpasses/noinline.jl @@ -17,5 +17,5 @@ include(joinpath("..", "testhelpers", "llvmpasses.jl")) return A + B end -# CHECK: attributes #{{[0-9]+}} = {{{([a-z]+ )*}} noinline {{([a-z]+ )*}}} +# CHECK: attributes #{{[0-9]+}} = {{{[^}]*}} noinline {{[^}]*}}} emit(simple_noinline, Float64, Float64) From e7995e4f4488cbe5e65a571993dbf3c29fdc603d Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Tue, 24 Aug 2021 15:30:25 -0400 Subject: [PATCH 108/135] ml-matches: fix performance trap (#41925) While normally we try to only call `jl_type_morespecific` on types with a non-empty intersection (to be more precise about ambiguity reporting), the only work we would do here (if the intersect is empty) would also be to call continue. Fixes #41518 --- src/gf.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/gf.c b/src/gf.c index 52180279ab5c2b..da59bc0085b4c3 100644 --- a/src/gf.c +++ b/src/gf.c @@ -2938,6 +2938,14 @@ static jl_value_t *ml_matches(jl_methtable_t *mt, int offs, int subt2 = matc2->fully_covers == FULLY_COVERS; // jl_subtype((jl_value_t*)type, (jl_value_t*)m2->sig) int rsubt2 = jl_egal((jl_value_t*)matc2->spec_types, m2->sig); jl_value_t *ti; + if (!subt && !subt2 && rsubt && rsubt2 && lim == -1 && ambig == NULL) + // these would only be filtered out of the list as + // ambiguous if they are also type-equal, as we + // aren't skipping matches and the user doesn't + // care if we report any ambiguities + continue; + if (jl_type_morespecific((jl_value_t*)m->sig, (jl_value_t*)m2->sig)) + continue; if (subt) { ti = (jl_value_t*)matc2->spec_types; isect2 = NULL; @@ -2946,18 +2954,11 @@ static jl_value_t *ml_matches(jl_methtable_t *mt, int offs, ti = (jl_value_t*)matc->spec_types; isect2 = NULL; } - else if (rsubt && rsubt2 && lim == -1 && ambig == NULL) { - // these would only be filtered out of the list as - // ambiguous if they are also type-equal, as we - // aren't skipping matches and the user doesn't - // care if we report any ambiguities - ti = jl_bottom_type; - } else { jl_type_intersection2((jl_value_t*)matc->spec_types, (jl_value_t*)matc2->spec_types, &env.match.ti, &isect2); ti = env.match.ti; } - if (ti != jl_bottom_type && !jl_type_morespecific((jl_value_t*)m->sig, (jl_value_t*)m2->sig)) { + if (ti != jl_bottom_type) { disjoint = 0; // m and m2 are ambiguous, but let's see if we can find another method (m3) // that dominates their intersection, and means we can ignore this From b8ad4f147f8104b7f402b964618bc8ab6546c552 Mon Sep 17 00:00:00 2001 From: Alex Arslan Date: Tue, 24 Aug 2021 13:10:42 -0700 Subject: [PATCH 109/135] Upgrade OpenBLAS to v0.3.17 (#41973) * Upgrade OpenBLAS to v0.3.17 This allows us to drop several patches. * Precision adjustments in doctests --- deps/Versions.make | 2 +- deps/checksums/openblas | 186 +++++++-------- deps/openblas.mk | 19 +- deps/openblas.version | 4 +- deps/patches/neoverse-generic-kernels.patch | 19 ++ ...-Only-filter-out-mavx-on-Sandybridge.patch | 221 ------------------ .../openblas-armv8-volatile-detecion.patch | 23 -- deps/patches/openblas-exshift.patch | 149 ------------ ...ilter-out-mavx-flag-on-zgemm-kernels.patch | 162 ------------- deps/patches/openblas-ofast-power.patch | 18 +- deps/patches/openblas-winexit.patch | 35 ++- stdlib/LinearAlgebra/src/LinearAlgebra.jl | 16 +- stdlib/LinearAlgebra/src/hessenberg.jl | 6 +- stdlib/OpenBLAS_jll/Project.toml | 2 +- 14 files changed, 152 insertions(+), 710 deletions(-) create mode 100644 deps/patches/neoverse-generic-kernels.patch delete mode 100644 deps/patches/openblas-Only-filter-out-mavx-on-Sandybridge.patch delete mode 100644 deps/patches/openblas-armv8-volatile-detecion.patch delete mode 100644 deps/patches/openblas-exshift.patch delete mode 100644 deps/patches/openblas-filter-out-mavx-flag-on-zgemm-kernels.patch diff --git a/deps/Versions.make b/deps/Versions.make index 2d29b0bf0b470d..fb23858d455557 100644 --- a/deps/Versions.make +++ b/deps/Versions.make @@ -79,7 +79,7 @@ BLASTRAMPOLINE_VER := 3.0.4 BLASTRAMPOLINE_JLL_NAME := libblastrampoline # OpenBLAS -OPENBLAS_VER := 0.3.13 +OPENBLAS_VER := 0.3.17 OPENBLAS_JLL_NAME := OpenBLAS # OpenLibm diff --git a/deps/checksums/openblas b/deps/checksums/openblas index 5a1668aa452544..597c5d5aa58682 100644 --- a/deps/checksums/openblas +++ b/deps/checksums/openblas @@ -1,92 +1,94 @@ -OpenBLAS.v0.3.13+7.aarch64-apple-darwin-libgfortran5.tar.gz/md5/c9800f7e24105c92a5205c77ddbc4227 -OpenBLAS.v0.3.13+7.aarch64-apple-darwin-libgfortran5.tar.gz/sha512/43703203a6d7c7aff8c8a257a2f5393d930e7e12064ff9a7890114dc250c28f0c73d735c4bbe09a811610cec6f4fe5079a806fb5898025c92067239dc70d6f62 -OpenBLAS.v0.3.13+7.aarch64-linux-gnu-libgfortran3.tar.gz/md5/ffb49e047b54a68b9de82ac3ae64a94d -OpenBLAS.v0.3.13+7.aarch64-linux-gnu-libgfortran3.tar.gz/sha512/745f30477562ec0bcf754a36e0c0082a60afea518dbe9fc46f95ee7547c33eece8717f6c9ee54bf1420a221ab7fb779dd4ccc98ca74164315975b7ac8e8b6979 -OpenBLAS.v0.3.13+7.aarch64-linux-gnu-libgfortran4.tar.gz/md5/ccdd01f36e19f8269750c93901c54bf7 -OpenBLAS.v0.3.13+7.aarch64-linux-gnu-libgfortran4.tar.gz/sha512/ef619a6b5d140253a5f310f975d1aca378a8419f75b90713baf73aa1f3be9cdc43ae96a8fc40bc7d3502947bce87de4fd5d869f16220bde1ced4e6730437ea5e -OpenBLAS.v0.3.13+7.aarch64-linux-gnu-libgfortran5.tar.gz/md5/cbe589a28fa89287502eb591d26c0a1d -OpenBLAS.v0.3.13+7.aarch64-linux-gnu-libgfortran5.tar.gz/sha512/7d894dda5e3eb124e17dcaa6ca7b02e29177f2ac678e18b6e57f6ce34c654c0dafb81fe470e93a42fa4b63f904b2cee00139cc149c7868d3f70b69313242187b -OpenBLAS.v0.3.13+7.aarch64-linux-musl-libgfortran3.tar.gz/md5/ebf835b3264f4b63cedac8c10f65316c -OpenBLAS.v0.3.13+7.aarch64-linux-musl-libgfortran3.tar.gz/sha512/2de3869ae6505789ff2ebbc83672ddb4f7a3f1610a88040ac9407dbafd23b7a0bdf19328964f4d901e7389636564fefb82442a1bb89a0d18e4a6441267d886b3 -OpenBLAS.v0.3.13+7.aarch64-linux-musl-libgfortran4.tar.gz/md5/3d20fe5e4c37e40eafd2a07ac5b11cf8 -OpenBLAS.v0.3.13+7.aarch64-linux-musl-libgfortran4.tar.gz/sha512/9dadabace2cec1260b2a02b42102453fa4c7e832c89d5c4f06b8a58ead30c2d926e6f615da03016aec596324619d34b7e25dec88e1dfa9725e420fbf6397c0ca -OpenBLAS.v0.3.13+7.aarch64-linux-musl-libgfortran5.tar.gz/md5/53c4a96fb47aed019efc780d0e9e4929 -OpenBLAS.v0.3.13+7.aarch64-linux-musl-libgfortran5.tar.gz/sha512/2e3ebec1e64f29308d7e61e80ff95dd7ff45a7bf7696639f6b786990d4e183c5cb8357e65f16b9c98058ff8d197a3e1e7c355a304e56c644fbe8b321d8941988 -OpenBLAS.v0.3.13+7.armv6l-linux-gnueabihf-libgfortran3.tar.gz/md5/59142e0c7a6e50c27e084f10982402c2 -OpenBLAS.v0.3.13+7.armv6l-linux-gnueabihf-libgfortran3.tar.gz/sha512/4e45b9a7087840edaf515af3a9ad15f6d5c2cbdb8be244b9c65542f6f6526e5f82fcd0939070b35a19a8ec1ea7c8886c82070359d74924b90f210ab3026b1d24 -OpenBLAS.v0.3.13+7.armv6l-linux-gnueabihf-libgfortran4.tar.gz/md5/2c00dddb46cd74324c023d9cea5d12e0 -OpenBLAS.v0.3.13+7.armv6l-linux-gnueabihf-libgfortran4.tar.gz/sha512/e4b6b07016c59727be3cc01fbfe1ceb2fc19bbddf96bffbd8a0b8bbf10e30768a7d8ed04052cbc53093d8f6d6f8d57c0d05d6692ba456bb8aa31a0f736617d33 -OpenBLAS.v0.3.13+7.armv6l-linux-gnueabihf-libgfortran5.tar.gz/md5/d98b02bba19262ebb4a6eae0971e19a8 -OpenBLAS.v0.3.13+7.armv6l-linux-gnueabihf-libgfortran5.tar.gz/sha512/f73413a520bf204d9c369dbc910e0df4b72e583ab31a66e5e64ae31e93464d6f8cc114be7c9f15738c900fa8762905f2c9ce198c45426eab22b119ac8fc489d3 -OpenBLAS.v0.3.13+7.armv6l-linux-musleabihf-libgfortran3.tar.gz/md5/5e34312709f68e06783e890d94447646 -OpenBLAS.v0.3.13+7.armv6l-linux-musleabihf-libgfortran3.tar.gz/sha512/f127d0df4a0b4d91c810990108f0f3daf89373f29002249edd6225330bdc804a0a2282e05ab128b15ec58c75098213481e26bb0e9a5a2b642da9c43457b9f9f9 -OpenBLAS.v0.3.13+7.armv6l-linux-musleabihf-libgfortran4.tar.gz/md5/02d6189238fe4ef41e791f558324e32c -OpenBLAS.v0.3.13+7.armv6l-linux-musleabihf-libgfortran4.tar.gz/sha512/fd5d4c2f43c4e98f0c28afdc43f2dfc97123fbe723c577688acaab959e96980c14b0ae76d150807da1814f9ea55dbc21a9cce9454d52804ba815cf8026d17117 -OpenBLAS.v0.3.13+7.armv6l-linux-musleabihf-libgfortran5.tar.gz/md5/14d77e7332ed0949342a4b659ce98088 -OpenBLAS.v0.3.13+7.armv6l-linux-musleabihf-libgfortran5.tar.gz/sha512/354113f9877ecb04dbdbc105991ee20c58d9bd49d499ee476af87135fbd277c7729e909e528843b5fd4ae2f076996ea74284ad384fc06584882ea5fdfd7d4206 -OpenBLAS.v0.3.13+7.armv7l-linux-gnueabihf-libgfortran3.tar.gz/md5/b32a6caa13c26d964a456f440a2df0ee -OpenBLAS.v0.3.13+7.armv7l-linux-gnueabihf-libgfortran3.tar.gz/sha512/4b19666ca3a32c1a145f89eed063cafea2eb468cafc3b47168977749a8e484e124b5008c58d00d40e4c7ba1b09669d7499fe259bd43c88ed0d064c326c85dea9 -OpenBLAS.v0.3.13+7.armv7l-linux-gnueabihf-libgfortran4.tar.gz/md5/4b15013643544594e7a8a4948b9a4db3 -OpenBLAS.v0.3.13+7.armv7l-linux-gnueabihf-libgfortran4.tar.gz/sha512/2fd0e4d5ec22e3ef831a60909cbf803ba88e16b7ba12269cf22bd14808fb25dccad597e0690530b704dc971c681f1c075f3663f4d7cb05998835e584cb9779b8 -OpenBLAS.v0.3.13+7.armv7l-linux-gnueabihf-libgfortran5.tar.gz/md5/7217154630d07a83fa84cbaf298d84e2 -OpenBLAS.v0.3.13+7.armv7l-linux-gnueabihf-libgfortran5.tar.gz/sha512/a9cded7959ef98027e1da87127464ac930dec3ba9c198296bf8c64918d31a8fcdd92d4d74e3aad2f3aff02553959e141986870873e01a5302c67e7efacc33616 -OpenBLAS.v0.3.13+7.armv7l-linux-musleabihf-libgfortran3.tar.gz/md5/65f601ff699b51719aacc4a495be5b82 -OpenBLAS.v0.3.13+7.armv7l-linux-musleabihf-libgfortran3.tar.gz/sha512/c96e4fadf74eea0c74ccc7d57670222d6bc097ceecc38211a742bdaf8c48491266302a96a33317ab4e8e19669b41f3051c5ca409c076ae1993f5218fa30f2cd6 -OpenBLAS.v0.3.13+7.armv7l-linux-musleabihf-libgfortran4.tar.gz/md5/7d0f0e432a372ce94cd127153b8976ee -OpenBLAS.v0.3.13+7.armv7l-linux-musleabihf-libgfortran4.tar.gz/sha512/b017bb4ffe9caec8410c72a80c5307e81cbfe84e4c148f3f99ca774efd17b47378b24ce95cfe6df45e8ee890ff0c326d480fabfbac0e494e25f620e82fdbbb8e -OpenBLAS.v0.3.13+7.armv7l-linux-musleabihf-libgfortran5.tar.gz/md5/398c894c743c181b4edcffebb5d91340 -OpenBLAS.v0.3.13+7.armv7l-linux-musleabihf-libgfortran5.tar.gz/sha512/c4c7acae9dfb49252dab6a7d0217e8caa8df707da72fcab3dcb5ea6449e42effd1a9df18531e8077d91ad8fdb323482a7fa405eda1a4660f48e59927ef33f525 -OpenBLAS.v0.3.13+7.i686-linux-gnu-libgfortran3.tar.gz/md5/ac7f07c75d419712e4ddad380fda0177 -OpenBLAS.v0.3.13+7.i686-linux-gnu-libgfortran3.tar.gz/sha512/4522c5b5924ff976e58ee30bbd0bf933baa2f705e3d68a83aaeeabaa8cd4cacf41edf05612f4616052d78ce04e70d62a411f8e0cc7ab9ab3fbc56dbae2615b67 -OpenBLAS.v0.3.13+7.i686-linux-gnu-libgfortran4.tar.gz/md5/08254b64198705d5062db0526d6d8cde -OpenBLAS.v0.3.13+7.i686-linux-gnu-libgfortran4.tar.gz/sha512/5d8c1062f15b11066d7400811492b8e2e1c33150bda4b74d7f9d7cd64529f0c0b89d7a1a2e644dc321be18fd3e3ba7dff92fe597f3d42aad5d903c8b26fa0e87 -OpenBLAS.v0.3.13+7.i686-linux-gnu-libgfortran5.tar.gz/md5/5f610eff8a8e7b24868a2b915419d4a3 -OpenBLAS.v0.3.13+7.i686-linux-gnu-libgfortran5.tar.gz/sha512/8967a180b57ada258aea76a39b8c71b718314460eeef2bad1e407be0c60a54f04a0b733944feb036c5fd2d67a8f3761babef10530dd871006f7d7ba366b4c95b -OpenBLAS.v0.3.13+7.i686-linux-musl-libgfortran3.tar.gz/md5/1867e826c4cdc6b6964bf2e7be43671e -OpenBLAS.v0.3.13+7.i686-linux-musl-libgfortran3.tar.gz/sha512/c7e7206361a4ee379c40a483aae1dc5357b8ba77e561fbf961cd7269674705c83ba2b5b09891b4567a330f9621d5a7bc0c323c8ec9d2385222b4afb57e010f8e -OpenBLAS.v0.3.13+7.i686-linux-musl-libgfortran4.tar.gz/md5/5a4511b55512387315e42555a1f35222 -OpenBLAS.v0.3.13+7.i686-linux-musl-libgfortran4.tar.gz/sha512/3381a32dd47d7106a131f8e6be89675c29b8ff496336e8f4dbc5bac13df3b1de9bd03a2c027b94ee43d66f4cb8fcab1545327552ac45280252046072dde3ebd7 -OpenBLAS.v0.3.13+7.i686-linux-musl-libgfortran5.tar.gz/md5/9766d92bb2a0bc7376d42537c0bff642 -OpenBLAS.v0.3.13+7.i686-linux-musl-libgfortran5.tar.gz/sha512/34149b0ae5ab26d4b5ec9f5a8a981eae713e355248c56af0d71eeb2720cd4e453d96fb9e885a48c94389759f5e015536b7a21d9720c6b46b167e6bbbccc717aa -OpenBLAS.v0.3.13+7.i686-w64-mingw32-libgfortran3.tar.gz/md5/3e13fa70512da79cb19d15899e967e8b -OpenBLAS.v0.3.13+7.i686-w64-mingw32-libgfortran3.tar.gz/sha512/c4e99d0bcfd9de4ddcdbf819872257a91e45cd778c7bf927b6a3c69e24d555d6a757236b08113160790a4a8fe0a3b258c17c8d43386a0d9ecf926e4e542b9a5b -OpenBLAS.v0.3.13+7.i686-w64-mingw32-libgfortran4.tar.gz/md5/724db97fb05d2418325b84eff736b0d6 -OpenBLAS.v0.3.13+7.i686-w64-mingw32-libgfortran4.tar.gz/sha512/4869bc155e2c5bbca2ea6a0107a2b12e7d7ec226dfa5ab81c8f46751f5e2a9342127c0c8ed24731cbfa05904db319ffdd907b248b725043d8bd089e911cf6808 -OpenBLAS.v0.3.13+7.i686-w64-mingw32-libgfortran5.tar.gz/md5/4fd5c17e2432dfbf2fbf6930c9b08617 -OpenBLAS.v0.3.13+7.i686-w64-mingw32-libgfortran5.tar.gz/sha512/92c4b8b61d9d4dfc8cc60c05cc1a8663e2cc33f3e0683d562f723939697237cfaf3925eb903ec2b443e1a943260c91e04029e582f9f07f2b3655ee5ed9812dad -OpenBLAS.v0.3.13+7.powerpc64le-linux-gnu-libgfortran3.tar.gz/md5/6b509bdecd697472c5c96b947a3d016f -OpenBLAS.v0.3.13+7.powerpc64le-linux-gnu-libgfortran3.tar.gz/sha512/494b8fa97c383554edd62d04b985f2fe25f1365d149af041d1d2d9c617df0fe12fff271e21a3811205e05412229e2f55043876ba6b553f22a7616653928b1908 -OpenBLAS.v0.3.13+7.powerpc64le-linux-gnu-libgfortran4.tar.gz/md5/5be5d102fd4c0537403a0fa8266a95d2 -OpenBLAS.v0.3.13+7.powerpc64le-linux-gnu-libgfortran4.tar.gz/sha512/2fb952a7da419d64f41b5fdff7c49e8e750f8724348180b52e61a50b4b55e5a3c3d072455d3ce870fb240b9c50c6f4572f6211813edb965ca41fa27efc85de6a -OpenBLAS.v0.3.13+7.powerpc64le-linux-gnu-libgfortran5.tar.gz/md5/9bb7b2ac52789cd7eba17e4b564d95d8 -OpenBLAS.v0.3.13+7.powerpc64le-linux-gnu-libgfortran5.tar.gz/sha512/a50700ab72ab169c91bd10eccb4a03231d0e223bcf3e158331af4a6805e2f17ab042eb6c9db335a800ab5b69554c0b9a5aa78c1f112c8b579f5148013afa15c2 -OpenBLAS.v0.3.13+7.x86_64-apple-darwin-libgfortran3.tar.gz/md5/2bfd33949884b29e2621bd4db9ea790b -OpenBLAS.v0.3.13+7.x86_64-apple-darwin-libgfortran3.tar.gz/sha512/87e32e09c5fb6da7396a13646a19ddc9f0aa6070060fba1e4f4490fc447c041a0b6ae68cd338e1f1b2d610bf61e28274823c81ae229768d6825104337d82e3d5 -OpenBLAS.v0.3.13+7.x86_64-apple-darwin-libgfortran4.tar.gz/md5/e0a3f443cd840d5a9cca3748c0fd247b -OpenBLAS.v0.3.13+7.x86_64-apple-darwin-libgfortran4.tar.gz/sha512/b4a55211a2a64fceb2eb89c1bbb06a5f658d4d81dcc6c67c1fc6a804ba16de8a05c341b81bae8b14788b85f772555785696a2b11b1cb6873ab9fbd174eebf1c1 -OpenBLAS.v0.3.13+7.x86_64-apple-darwin-libgfortran5.tar.gz/md5/3acd992bd55a527ff96cbc1fd208300a -OpenBLAS.v0.3.13+7.x86_64-apple-darwin-libgfortran5.tar.gz/sha512/192300b6480efe523e3a196570743e3c091d9d29c6f16cb3f5f951b344e8ecc5a76f235c8fa2b2a9bd56c8dc394fca447c2bd1d4102ad7f9823ab71436154dbd -OpenBLAS.v0.3.13+7.x86_64-linux-gnu-libgfortran3.tar.gz/md5/35ede94f298e95ff772e3655692da81c -OpenBLAS.v0.3.13+7.x86_64-linux-gnu-libgfortran3.tar.gz/sha512/109fbc3ee23528640011df500f7843bec3f42d92b6be99e2101bfd0c6bb798d5c5a0c8a9d2567d11e50bdf54213347ea204c383660d2fd6445ae0735f210d211 -OpenBLAS.v0.3.13+7.x86_64-linux-gnu-libgfortran4.tar.gz/md5/5d97a16fb7ba45d34aee0d1b55f81008 -OpenBLAS.v0.3.13+7.x86_64-linux-gnu-libgfortran4.tar.gz/sha512/f957549494ec3c11fbb73cad4b43d8a39a7f0e509a3f797cd35898f40ed577aad27cc721a5720eb38e0ccd5064915a4ca93b67e517f7fa1cef86fbe3f88c2529 -OpenBLAS.v0.3.13+7.x86_64-linux-gnu-libgfortran5.tar.gz/md5/85903515954b13d71dfc1cfed5364000 -OpenBLAS.v0.3.13+7.x86_64-linux-gnu-libgfortran5.tar.gz/sha512/ee3fdeede35b52987565e55c96a1a47964cf1da52b25753302c2ac4671b2921a70656a5f9e39bf1b7db0d6037c305f66b4aa22529713239ca30c322f5c3d8f97 -OpenBLAS.v0.3.13+7.x86_64-linux-musl-libgfortran3.tar.gz/md5/b9a86f939ec7d76674d67653d3acdfee -OpenBLAS.v0.3.13+7.x86_64-linux-musl-libgfortran3.tar.gz/sha512/8a9d10605d9fad833ece78bc0c4690e43050e5e276b0c76ff194b617134e05261db2b385fe2c4b0b2313a3be107731b4cc71dae79d6e403e64a6ca635a3d4b47 -OpenBLAS.v0.3.13+7.x86_64-linux-musl-libgfortran4.tar.gz/md5/6a4a082c4d73cb6dad69460deb75afdd -OpenBLAS.v0.3.13+7.x86_64-linux-musl-libgfortran4.tar.gz/sha512/8fa8c2f07ff044acc78caaf7e34f6e299567ac82436059c70d9a149ffd03d0d257a009592f845e22554a17dbd59fb13c23582a0e4131a186139c9be9c71b9f2d -OpenBLAS.v0.3.13+7.x86_64-linux-musl-libgfortran5.tar.gz/md5/50148e4dc8881c9f1f4c2bc936c3f59e -OpenBLAS.v0.3.13+7.x86_64-linux-musl-libgfortran5.tar.gz/sha512/df0019201f71a12867deb872d3a3f7b3c07919bb779b3f3f5612d52f9c02bba1c19e230c81c8421e32b5cf1140dc388f1dfae3379c081cecb4a516f1d28a3788 -OpenBLAS.v0.3.13+7.x86_64-unknown-freebsd-libgfortran3.tar.gz/md5/87b58444e006bb680e8139b2ee7bc998 -OpenBLAS.v0.3.13+7.x86_64-unknown-freebsd-libgfortran3.tar.gz/sha512/c32638c812a3cc4e3c3916b6a9bf572ac202b2101946a18a7af89de1cd3171a44f9d9308a6de822bd703acd96533c963ad8a8205a1200039540191cd03fe1f6b -OpenBLAS.v0.3.13+7.x86_64-unknown-freebsd-libgfortran4.tar.gz/md5/f8a07c961fa2b6d268ff1b3f4e02b729 -OpenBLAS.v0.3.13+7.x86_64-unknown-freebsd-libgfortran4.tar.gz/sha512/b3faaa4155971047a8f58123da5dbf51cd6cac574a46e4a339b2be0570f1868fddbe9b46ce07f75fb561bb5da42bf19466035a05286832a85f1f39c58265bfb4 -OpenBLAS.v0.3.13+7.x86_64-unknown-freebsd-libgfortran5.tar.gz/md5/67d69caa1877b74ca652f0e96718ddde -OpenBLAS.v0.3.13+7.x86_64-unknown-freebsd-libgfortran5.tar.gz/sha512/bc72e2df6e0dec6962cd32b77f49ec93b05b34dbc95c0b0c31da6158d3a5f497f6321a895f3faa48c82ee956fbd8e82346bb8d8a20a9639e2e689f0b85ab5c2e -OpenBLAS.v0.3.13+7.x86_64-w64-mingw32-libgfortran3.tar.gz/md5/dc755ddb59511ef049daf85a38ef0804 -OpenBLAS.v0.3.13+7.x86_64-w64-mingw32-libgfortran3.tar.gz/sha512/fa5a559165b97cc5ca24d5df02dfeb1f97b8619512d8f99e3c8c8ee800aec0d3ca56ac4170569dafee7cec738e9abc5017958c153bd44d19d60fbecac53a0ee2 -OpenBLAS.v0.3.13+7.x86_64-w64-mingw32-libgfortran4.tar.gz/md5/ff56c35358fb846827f8f869fdca4b21 -OpenBLAS.v0.3.13+7.x86_64-w64-mingw32-libgfortran4.tar.gz/sha512/c8c0029c9b95f5a11dfc84bd02b944ed96de5c96835b2e6dc5e8c401fc37b667f8ea956f3715794b01be68ea86e0c74b4ebd22f728d1f9777516bfdca944c1b3 -OpenBLAS.v0.3.13+7.x86_64-w64-mingw32-libgfortran5.tar.gz/md5/e5bbc60da2dce3c4abe0583cff4b985e -OpenBLAS.v0.3.13+7.x86_64-w64-mingw32-libgfortran5.tar.gz/sha512/344dac288566886013b59c40877b879578b11f57b90433e65909b56b7e06416c0ceffedf08cc3d05e08514a098309ae492fd57c30dc97737cdede1aebed2ea2d +OpenBLAS.v0.3.17+0.aarch64-apple-darwin-libgfortran5.tar.gz/md5/6d1adab725ba1f1e63a773610120c415 +OpenBLAS.v0.3.17+0.aarch64-apple-darwin-libgfortran5.tar.gz/sha512/004b7b9babaeded60e2d4d24bc07f6c5edf04ee6564cf9b2ee5f39e72859a2100df637631d79cbb4be26b740141d15c9794c443d2798850dbf1cdaa47c1ee1ed +OpenBLAS.v0.3.17+0.aarch64-linux-gnu-libgfortran3.tar.gz/md5/d18088e102948fe95b13ef8a0b1420fc +OpenBLAS.v0.3.17+0.aarch64-linux-gnu-libgfortran3.tar.gz/sha512/855860b44af6c9c9b40f3e07e6c6db2b54714a211788bee377becd9da58f17bffe8118c6317326b47cad6a8525a2d55f355fde1d4f7ecf75731cd48032deae21 +OpenBLAS.v0.3.17+0.aarch64-linux-gnu-libgfortran4.tar.gz/md5/730771a8901aa54e412551f4c3c14fed +OpenBLAS.v0.3.17+0.aarch64-linux-gnu-libgfortran4.tar.gz/sha512/5beb259e1e7e3edb5b60dcbdc97683c265accaaea3c0e22e688d09cb82ded75413e7ed6ac75f1d87465191baa387f012b50a2ddf921732ff5642b5d0e379ff3d +OpenBLAS.v0.3.17+0.aarch64-linux-gnu-libgfortran5.tar.gz/md5/b7d37884a729c0cad1f90407e6357649 +OpenBLAS.v0.3.17+0.aarch64-linux-gnu-libgfortran5.tar.gz/sha512/befc096f478947c4361ffe29256ab8f65f0d8d07a0932caa16ee43339422a8af9b79ce9a7bc2268ecc0edde57a874fe086dfd08a758d310572c95a2baff24d22 +OpenBLAS.v0.3.17+0.aarch64-linux-musl-libgfortran3.tar.gz/md5/f9fa013c02ed7dd0b8cee2c3dce69807 +OpenBLAS.v0.3.17+0.aarch64-linux-musl-libgfortran3.tar.gz/sha512/a6707805d4d449f779a96d8e92483d094c604045e2f1e1c9ad40e30e6d38642b9bb232c4bc41e27d12eabb280cb5c3107240b6f5230502116bb2d4ae3b31172f +OpenBLAS.v0.3.17+0.aarch64-linux-musl-libgfortran4.tar.gz/md5/e355b1382d91b69c40278c955d0207f2 +OpenBLAS.v0.3.17+0.aarch64-linux-musl-libgfortran4.tar.gz/sha512/67e6e82f5fd5139f3d8e62eb7b93440da1c4e78acd3662e31c631a9f15219bc1e713428973a128d9f9993941966eda4ae6c711ebed7d19d331b1b66e8f1e2c8a +OpenBLAS.v0.3.17+0.aarch64-linux-musl-libgfortran5.tar.gz/md5/d64af394c32a8e85490a6f82fea2bcfc +OpenBLAS.v0.3.17+0.aarch64-linux-musl-libgfortran5.tar.gz/sha512/91bcedc5d0bb806a487446049c604f3c149ff7f1ac28c9f24468986181bd10e57ac78613b8426f4626d634752b1de6c5f953ce99c3570451e3f3ec44bffa42da +OpenBLAS.v0.3.17+0.armv6l-linux-gnueabihf-libgfortran3.tar.gz/md5/c4e7eb9669ed6882c4dba5f691e67ab2 +OpenBLAS.v0.3.17+0.armv6l-linux-gnueabihf-libgfortran3.tar.gz/sha512/50f9053ba121c9c593fe08114562ba0d11a1c8bc46eecb376dbab06c57741d046de281ebc9499d5a87a7682782d3429730d262d7ae05d2c54ac7bb71635a4aa2 +OpenBLAS.v0.3.17+0.armv6l-linux-gnueabihf-libgfortran4.tar.gz/md5/0c57cf0f5e6b097e7c7b5162e3d3fa93 +OpenBLAS.v0.3.17+0.armv6l-linux-gnueabihf-libgfortran4.tar.gz/sha512/ee1b0842276366f2e5e6d5a600fd9e3aa6915f3c96db0770be7fd9fbf9b9fab7f709a8087abf9f7ae1f291178730fcd5791c928255e8ad8d9b818b62a366f95d +OpenBLAS.v0.3.17+0.armv6l-linux-gnueabihf-libgfortran5.tar.gz/md5/6514e09f96619e183bcecf196ee03356 +OpenBLAS.v0.3.17+0.armv6l-linux-gnueabihf-libgfortran5.tar.gz/sha512/b2e091f720009e970f62f53846b840a6e1106ce17db709bc940308f1c4f0bae02ef312aab3511e62147f1ecd6121a3ce8263d94931acb53122442f78e1859160 +OpenBLAS.v0.3.17+0.armv6l-linux-musleabihf-libgfortran3.tar.gz/md5/7e61f954bd743ac2c36cc18d0e956b80 +OpenBLAS.v0.3.17+0.armv6l-linux-musleabihf-libgfortran3.tar.gz/sha512/d4589f1b3f199e50ea37ad0dde8906cffe5bbc559005b646e2f69b9023159a2f20d7b0eb8b53bd623fc9c71a4f785bb3e040f9c6aa9f850424388c6c8641bbd9 +OpenBLAS.v0.3.17+0.armv6l-linux-musleabihf-libgfortran4.tar.gz/md5/c3f6f6a85b8e28d8a9bc5cc9d8609045 +OpenBLAS.v0.3.17+0.armv6l-linux-musleabihf-libgfortran4.tar.gz/sha512/0315eb6fc19e42b1d2aaca492fcbcb646b628af40885e579c232979a8325abd181f88ec879cc04bd91d2a724de04e0c8988d3e2b5045d5c775a5833d39a65166 +OpenBLAS.v0.3.17+0.armv6l-linux-musleabihf-libgfortran5.tar.gz/md5/c1224f944d53902038f590cbb3298943 +OpenBLAS.v0.3.17+0.armv6l-linux-musleabihf-libgfortran5.tar.gz/sha512/3083f9943ede3b3ab3ddd2d24ec835878ee5d85d43c7b0473f0b531e874eddbf87e69e378aea8f07f719bd1850f5da96d96c8c52a58b4af7c9ccb8916b93ad38 +OpenBLAS.v0.3.17+0.armv7l-linux-gnueabihf-libgfortran3.tar.gz/md5/3b15317daaee8186e8e35acc5176452d +OpenBLAS.v0.3.17+0.armv7l-linux-gnueabihf-libgfortran3.tar.gz/sha512/90cba606ee49d4d1ccd971df87668cf43d808fc98ea66bafc791362d38ae01f284d5a01ffe266ba0333f5dcc7dfbe81807526ffa43009a12020f38b2e0ef042f +OpenBLAS.v0.3.17+0.armv7l-linux-gnueabihf-libgfortran4.tar.gz/md5/48c09596f1e5f92d42db46398582a7e4 +OpenBLAS.v0.3.17+0.armv7l-linux-gnueabihf-libgfortran4.tar.gz/sha512/07bca40a4381b2e846d01bc09fa81b4aaf2e03ade52fe11df47f9c9442d03743f33edcd6415ca9c8a1557cf996fac5ec7905a60b3a013fa8c2b3b5488df13fca +OpenBLAS.v0.3.17+0.armv7l-linux-gnueabihf-libgfortran5.tar.gz/md5/1678aae19e570cdc7cb22d4bd8f67c81 +OpenBLAS.v0.3.17+0.armv7l-linux-gnueabihf-libgfortran5.tar.gz/sha512/5530e95398b372e78aab45ec6e3d59408ed0321e3da487046d58a359399e0b624cc7aa1ab788ecf6d36f2fbb44bf7ed26fd4d1eb0aebb414886b0279491d09ea +OpenBLAS.v0.3.17+0.armv7l-linux-musleabihf-libgfortran3.tar.gz/md5/2fa577470606aa8c97156a3ba44fe65b +OpenBLAS.v0.3.17+0.armv7l-linux-musleabihf-libgfortran3.tar.gz/sha512/ac57336720b6b79512d08423de65803c8b2d854a67adf5e3766628d1d67b7fc153cb6cdd463b3d801b6cef6bd38a2174a861c25825073a6c221b96ddfc7914e3 +OpenBLAS.v0.3.17+0.armv7l-linux-musleabihf-libgfortran4.tar.gz/md5/93d929aac8e7e3851be1d23f7d589b0d +OpenBLAS.v0.3.17+0.armv7l-linux-musleabihf-libgfortran4.tar.gz/sha512/5be22d3aa0b5e2a2d6fed79e2669c89630b236c506d1c6ed55dfa1158903c298b827583a326a413f1ea5ae336de6d3d508b76f72e3e1e0729643b86543192f7b +OpenBLAS.v0.3.17+0.armv7l-linux-musleabihf-libgfortran5.tar.gz/md5/f5efd57ea0e7acf8c47e7759759f8294 +OpenBLAS.v0.3.17+0.armv7l-linux-musleabihf-libgfortran5.tar.gz/sha512/1d51b3521c184a39bd5471ba8b0fced85c51d9d69580e18468b26d77a94d050e8cb9e2cac0ca57a598cd90e428b75b2002497101bb7c148a28c9f1998dc09ce8 +OpenBLAS.v0.3.17+0.i686-linux-gnu-libgfortran3.tar.gz/md5/c6b1957bbda6aec3941a54614aef5c8f +OpenBLAS.v0.3.17+0.i686-linux-gnu-libgfortran3.tar.gz/sha512/261db11d44856431a714713fd06f8de67fee40849a693c862958a8eee157b7c99ad9a928bfff263413cbc157331fabf42e1139d9ca122903d25eb750ac873d6a +OpenBLAS.v0.3.17+0.i686-linux-gnu-libgfortran4.tar.gz/md5/778227c00545c094e2db0116764bfc4b +OpenBLAS.v0.3.17+0.i686-linux-gnu-libgfortran4.tar.gz/sha512/98b66a03a2e7a4abce03dc5f8d5bd10908d2caf84efdde35df2a2ac026c1287feafbec13ac10c42161e5cd21e02005fe56cb86ef0fd5ffbef260a965e913b1be +OpenBLAS.v0.3.17+0.i686-linux-gnu-libgfortran5.tar.gz/md5/c8a81d90002d980b169e14d3f45de420 +OpenBLAS.v0.3.17+0.i686-linux-gnu-libgfortran5.tar.gz/sha512/907bcbb1560e18b175b9d4251e634e288433b113d91e27780ca1307d6678ac67e7c8068ae675793475ce8004d1de06b522d6203a241c1cece85efc3f54e55d0a +OpenBLAS.v0.3.17+0.i686-linux-musl-libgfortran3.tar.gz/md5/dd84709d38c98ef8590293022b4e793b +OpenBLAS.v0.3.17+0.i686-linux-musl-libgfortran3.tar.gz/sha512/667206ba5f9d57bab2b7355c151dad8deb51d728854652a41274f092a8415509c80de4f199ae7532750fbd92024b2a09aeaf02f3e468edb67e15e06745f57c41 +OpenBLAS.v0.3.17+0.i686-linux-musl-libgfortran4.tar.gz/md5/7d7e4d19dbfa8df28c3bd2fdf3159e25 +OpenBLAS.v0.3.17+0.i686-linux-musl-libgfortran4.tar.gz/sha512/0afbb8b13838df1d65390062d57ab4821598a57b9e2bdd1e2fad2429f7379ef3a3732c35fd4b48912dcbe913d7f092cbc780e1f57fdcf6e0c17a1c09824493b5 +OpenBLAS.v0.3.17+0.i686-linux-musl-libgfortran5.tar.gz/md5/e824b8e0b9ff9801825cdca46fbdf400 +OpenBLAS.v0.3.17+0.i686-linux-musl-libgfortran5.tar.gz/sha512/72f64d83c74ba1e14fc920e3532ad1f999315e4c735faeac8cb435427c07e1bdcd61c3e68740853822d789931ffa72194785df3dab9734604d66af509653a2dc +OpenBLAS.v0.3.17+0.i686-w64-mingw32-libgfortran3.tar.gz/md5/0590c643b7d3fd97ce9cbd0ae1eaef58 +OpenBLAS.v0.3.17+0.i686-w64-mingw32-libgfortran3.tar.gz/sha512/070303eded91ef484140068f1291dbebac763e1336fdb860affe4246c16e156751a7e05e51591f3e39d1a4331d84a53a009f45b49be56e6372ec81a7630c8d39 +OpenBLAS.v0.3.17+0.i686-w64-mingw32-libgfortran4.tar.gz/md5/e1e5bd791931b93f4b9da96619796479 +OpenBLAS.v0.3.17+0.i686-w64-mingw32-libgfortran4.tar.gz/sha512/09cb091c7a065697d72320da18fb29a8fa9c49d97047a03f1a881add304d5613829083a472ea082cc3779ada82f138eaaffae9fd5233a47ac77777460465e058 +OpenBLAS.v0.3.17+0.i686-w64-mingw32-libgfortran5.tar.gz/md5/f78f0e4c205ead8826d93b35268ef579 +OpenBLAS.v0.3.17+0.i686-w64-mingw32-libgfortran5.tar.gz/sha512/cb5eb6c2d037d46cbcf7540114a03a1a41a97682460fce7156bfa576bc3c75dfc16d4c8b6974ec677b429fd5063932e9f9611f8c7064ed585764999c11fb1b02 +OpenBLAS.v0.3.17+0.powerpc64le-linux-gnu-libgfortran3.tar.gz/md5/82368cc4d60d37483f40d447bf850af0 +OpenBLAS.v0.3.17+0.powerpc64le-linux-gnu-libgfortran3.tar.gz/sha512/9ca84d891a0323f6bf4ac757eaff2305e66097bebda346280b2a7390fe091ab0c0ad8770e8b32c7cdd273a162f36ee43aedd94536a543205987767713b2915e3 +OpenBLAS.v0.3.17+0.powerpc64le-linux-gnu-libgfortran4.tar.gz/md5/58a3b9eeaa72bb9eeaa83eb6bafa49cb +OpenBLAS.v0.3.17+0.powerpc64le-linux-gnu-libgfortran4.tar.gz/sha512/4a653a13749a580c1b0f907dfc1597f24338913183a04f252a7ed00c7c5e32b48246fe4e0028a717fabd1129fa81e2aa42bcb23122541c81d2397e383f430bcb +OpenBLAS.v0.3.17+0.powerpc64le-linux-gnu-libgfortran5.tar.gz/md5/9335da7abeb89cefb6872560f76b5091 +OpenBLAS.v0.3.17+0.powerpc64le-linux-gnu-libgfortran5.tar.gz/sha512/8406ef5799d367c85e33f51c502f4d145930da64f78fe254611a425fd68952d3d71ce62b27232535fb7429b05ff2dc95eb2174e63d93d54aab52714355ff99b7 +OpenBLAS.v0.3.17+0.x86_64-apple-darwin-libgfortran3.tar.gz/md5/552724d8d498de5343f95acf2cc43c4a +OpenBLAS.v0.3.17+0.x86_64-apple-darwin-libgfortran3.tar.gz/sha512/6c71a9ba1f0008ea90ba637fddd79fa6c331e52473ca5521655956d9a5059657d550092760855840eb52060b5c33020839771bad23c061d81d47c1fdaf28397b +OpenBLAS.v0.3.17+0.x86_64-apple-darwin-libgfortran4.tar.gz/md5/611d1d1522197db50deb468a6882dd2b +OpenBLAS.v0.3.17+0.x86_64-apple-darwin-libgfortran4.tar.gz/sha512/392c080e557584771b875ea7bddf5d9e8d77d3571f9c5a22cab92b749c7e48444bdb17c909745dfc92859bcfb8b9613abd71b4996fe389291905aa2cb8255e34 +OpenBLAS.v0.3.17+0.x86_64-apple-darwin-libgfortran5.tar.gz/md5/3d45861e231ba250feab838ae24e2b12 +OpenBLAS.v0.3.17+0.x86_64-apple-darwin-libgfortran5.tar.gz/sha512/8315f5832fc3653a1b57ec8a1d9551066ee506e85344ee571b9c93648986f71c35c3bae51f9a8e80a8268501e9810974863975f9c12211c3c08da165bc0c1592 +OpenBLAS.v0.3.17+0.x86_64-linux-gnu-libgfortran3.tar.gz/md5/102b3ca4e488f62a3489ef2d4714e65e +OpenBLAS.v0.3.17+0.x86_64-linux-gnu-libgfortran3.tar.gz/sha512/5075492ae2336d261c9549263a37611d51bb82d6ee1bef4e67bd6cf2927d621a4a21a6cf3a6d878bad1ad7e10d0900e74e6d020ba0c3f9b651650fe9e5efb0c2 +OpenBLAS.v0.3.17+0.x86_64-linux-gnu-libgfortran4.tar.gz/md5/782e81b4d7893fd93443cc20e5adb876 +OpenBLAS.v0.3.17+0.x86_64-linux-gnu-libgfortran4.tar.gz/sha512/425142132b0e330bb12a86c54779ea87ad90ae05d7e44121e19855412b47e629a53b5aa45a9550f6266a7a8e9194f4f89ef070e1b95bdab9716b0f79369bb9c2 +OpenBLAS.v0.3.17+0.x86_64-linux-gnu-libgfortran5.tar.gz/md5/243da9baba80b24bad684e74f01b844c +OpenBLAS.v0.3.17+0.x86_64-linux-gnu-libgfortran5.tar.gz/sha512/6ddab469dffaface8f2ab6b8707b132c7e8c86f3f6354ea53a12e606ad22278fc6bcafdafda678bd5e31778dda5b4000ae36b3e2096ac1d0cfefedea0549e98e +OpenBLAS.v0.3.17+0.x86_64-linux-musl-libgfortran3.tar.gz/md5/04b662adab755a56e394de2acdd3e6ff +OpenBLAS.v0.3.17+0.x86_64-linux-musl-libgfortran3.tar.gz/sha512/f566fc0d492736cbb9c58b6166378a50f9e0c2b6e3f5dafd841ce55042cc87f8bf4fd4a4771a8301dff013b1151da50907109e91f15eed3cadbb59e2d59cce4e +OpenBLAS.v0.3.17+0.x86_64-linux-musl-libgfortran4.tar.gz/md5/a50ad857c166df8ad8e7ef130ca4847d +OpenBLAS.v0.3.17+0.x86_64-linux-musl-libgfortran4.tar.gz/sha512/44e10a9f57ec6023a9cce96f9b7b069ae6127abe8afdd673fc86e99aa86eb2c394401d4fd29dfb3708de19e6cc723c797cd42bc6259e663c25179c13a78083ef +OpenBLAS.v0.3.17+0.x86_64-linux-musl-libgfortran5.tar.gz/md5/cd30d36e87bfb2b3c682e12fd23896f6 +OpenBLAS.v0.3.17+0.x86_64-linux-musl-libgfortran5.tar.gz/sha512/7f19efc20c3498be51d7a6c892ec74cf9183068d1bd15190800cc93ee84267d1f71cdac3f3684fbf8a9e2fffed5dd1c4bf69204e8533ddf4ed91a82bf8608405 +OpenBLAS.v0.3.17+0.x86_64-unknown-freebsd-libgfortran3.tar.gz/md5/618d5c45e8e5b83a6a4905cdc1a2ea6c +OpenBLAS.v0.3.17+0.x86_64-unknown-freebsd-libgfortran3.tar.gz/sha512/9b0af80e94a450098a771eaee55f714845e3f522f38d420ad34c8b79f03889384acb2cdfd563c5a01102e91af98c3e781bf499c9aabac93d58b14665a9158553 +OpenBLAS.v0.3.17+0.x86_64-unknown-freebsd-libgfortran4.tar.gz/md5/86c97dca50aedd3cf2d94c3f85c9d40a +OpenBLAS.v0.3.17+0.x86_64-unknown-freebsd-libgfortran4.tar.gz/sha512/db6c7b5c8a364e0ed42d65953dd05ac5ee436006de7495a00c4224bc91a6def8513542f766217c86a44214580f37e58f6e739a8b24312288ebd2169acd2213c6 +OpenBLAS.v0.3.17+0.x86_64-unknown-freebsd-libgfortran5.tar.gz/md5/dcbd865a7cccaec4fc187784138a785b +OpenBLAS.v0.3.17+0.x86_64-unknown-freebsd-libgfortran5.tar.gz/sha512/5d16120bea378d60fb6494421c24c9c5a02e78c1e38c7d1d1ffa6cc857805926420f0bd9678ba749809f15ac2a5c3f89a4f0a1ae015008b8f6be54c774ee6078 +OpenBLAS.v0.3.17+0.x86_64-w64-mingw32-libgfortran3.tar.gz/md5/1cd64551545735e15e19144636f79550 +OpenBLAS.v0.3.17+0.x86_64-w64-mingw32-libgfortran3.tar.gz/sha512/3d00581f9f7a557f906fb93b755c22794ea4033d09ae0b3241fcac3275d924a6abec0353f46ddf9bb1910a702922b106a744275d70c4a41964469c227802dff8 +OpenBLAS.v0.3.17+0.x86_64-w64-mingw32-libgfortran4.tar.gz/md5/5884cbad0a794115cf686092aadfc740 +OpenBLAS.v0.3.17+0.x86_64-w64-mingw32-libgfortran4.tar.gz/sha512/397ca83c411b58ccdab97c6714042540a92e889d8d40350d2b6daf332526c7d28fbd8956aedaa3509e138fb7577edabf750f74b19ca8f821493bc95324dc77bf +OpenBLAS.v0.3.17+0.x86_64-w64-mingw32-libgfortran5.tar.gz/md5/e21769fbfb75901961290b8c4bf9269a +OpenBLAS.v0.3.17+0.x86_64-w64-mingw32-libgfortran5.tar.gz/sha512/b28c9d6379f084f7a08222d7907ef5174fd52a6a13b189254fdea9911dd6db45e45924c9f24e00ec2e801669f50460d993288f0047b019a2ffa3bbb0fb4a5637 +openblas-d909f9f3d4fc4ccff36d69f178558df154ba1002.tar.gz/md5/4acd59865ca8b50c823bef1354148930 +openblas-d909f9f3d4fc4ccff36d69f178558df154ba1002.tar.gz/sha512/227ee7decccf9bdd2e5754757f590e32ada95b576db9eddc2c74ef06d35aba1db9438acaf57750184baacac741917f7f5ad9f15991d31314480db371fe59cc17 diff --git a/deps/openblas.mk b/deps/openblas.mk index ee6712d883de63..6eb0e43c4d4762 100644 --- a/deps/openblas.mk +++ b/deps/openblas.mk @@ -103,27 +103,12 @@ $(BUILDDIR)/$(OPENBLAS_SRC_DIR)/openblas-ofast-power.patch-applied: $(BUILDDIR)/ patch -p1 -f < $(SRCDIR)/patches/openblas-ofast-power.patch echo 1 > $@ -$(BUILDDIR)/$(OPENBLAS_SRC_DIR)/openblas-exshift.patch-applied: $(BUILDDIR)/$(OPENBLAS_SRC_DIR)/openblas-ofast-power.patch-applied +$(BUILDDIR)/$(OPENBLAS_SRC_DIR)/neoverse-generic-kernels.patch-applied: $(BUILDDIR)/$(OPENBLAS_SRC_DIR)/openblas-ofast-power.patch-applied cd $(BUILDDIR)/$(OPENBLAS_SRC_DIR) && \ 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-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-applied - cd $(BUILDDIR)/$(OPENBLAS_SRC_DIR) && \ - patch -p1 -f < $(SRCDIR)/patches/openblas-Only-filter-out-mavx-on-Sandybridge.patch - echo 1 > $@ - -$(BUILDDIR)/$(OPENBLAS_SRC_DIR)/openblas-armv8-volatile-detecion.patch-applied: $(BUILDDIR)/$(OPENBLAS_SRC_DIR)/openblas-Only-filter-out-mavx-on-Sandybridge.patch-applied - cd $(BUILDDIR)/$(OPENBLAS_SRC_DIR) && \ - patch -p1 -f < $(SRCDIR)/patches/openblas-armv8-volatile-detecion.patch - echo 1 > $@ - -$(BUILDDIR)/$(OPENBLAS_SRC_DIR)/build-configured: $(BUILDDIR)/$(OPENBLAS_SRC_DIR)/openblas-armv8-volatile-detecion.patch-applied +$(BUILDDIR)/$(OPENBLAS_SRC_DIR)/build-configured: $(BUILDDIR)/$(OPENBLAS_SRC_DIR)/neoverse-generic-kernels.patch-applied echo 1 > $@ $(BUILDDIR)/$(OPENBLAS_SRC_DIR)/build-compiled: $(BUILDDIR)/$(OPENBLAS_SRC_DIR)/build-configured diff --git a/deps/openblas.version b/deps/openblas.version index 7814f788417671..346e75dac614bc 100644 --- a/deps/openblas.version +++ b/deps/openblas.version @@ -1,2 +1,2 @@ -OPENBLAS_BRANCH=v0.3.13 -OPENBLAS_SHA1=d2b11c47774b9216660e76e2fc67e87079f26fa1 +OPENBLAS_BRANCH=v0.3.17 +OPENBLAS_SHA1=d909f9f3d4fc4ccff36d69f178558df154ba1002 diff --git a/deps/patches/neoverse-generic-kernels.patch b/deps/patches/neoverse-generic-kernels.patch new file mode 100644 index 00000000000000..ab37e3783bf3e5 --- /dev/null +++ b/deps/patches/neoverse-generic-kernels.patch @@ -0,0 +1,19 @@ +diff --git a/kernel/arm64/KERNEL.NEOVERSEN1 b/kernel/arm64/KERNEL.NEOVERSEN1 +index ea010db4..074d7215 100644 +--- a/kernel/arm64/KERNEL.NEOVERSEN1 ++++ b/kernel/arm64/KERNEL.NEOVERSEN1 +@@ -91,10 +91,10 @@ IDAMAXKERNEL = iamax_thunderx2t99.c + ICAMAXKERNEL = izamax_thunderx2t99.c + IZAMAXKERNEL = izamax_thunderx2t99.c + +-SNRM2KERNEL = scnrm2_thunderx2t99.c +-DNRM2KERNEL = dznrm2_thunderx2t99.c +-CNRM2KERNEL = scnrm2_thunderx2t99.c +-ZNRM2KERNEL = dznrm2_thunderx2t99.c ++SNRM2KERNEL = nrm2.S ++DNRM2KERNEL = nrm2.S ++CNRM2KERNEL = znrm2.S ++ZNRM2KERNEL = znrm2.S + + DDOTKERNEL = dot_thunderx2t99.c + SDOTKERNEL = dot_thunderx2t99.c diff --git a/deps/patches/openblas-Only-filter-out-mavx-on-Sandybridge.patch b/deps/patches/openblas-Only-filter-out-mavx-on-Sandybridge.patch deleted file mode 100644 index 10ba3b4a5c6b5f..00000000000000 --- a/deps/patches/openblas-Only-filter-out-mavx-on-Sandybridge.patch +++ /dev/null @@ -1,221 +0,0 @@ -From c4da892ba0798f8697e7b3219fd631651647e45f Mon Sep 17 00:00:00 2001 -From: Martin Kroeker -Date: Fri, 14 May 2021 23:19:10 +0200 -Subject: [PATCH 2/2] Only filter out -mavx on Sandybridge ZGEMM/ZTRMM kernels - ---- - kernel/Makefile.L3 | 86 ++++++++++++++++++++++++++++++++++++---------- - 1 file changed, 68 insertions(+), 18 deletions(-) - -diff --git a/kernel/Makefile.L3 b/kernel/Makefile.L3 -index be10ee01..2d9e3ec3 100644 ---- a/kernel/Makefile.L3 -+++ b/kernel/Makefile.L3 -@@ -818,8 +818,10 @@ ifeq ($(OS), AIX) - m4 zgemm_kernel_n.s > zgemm_kernel_n_nomacros.s - $(CC) $(CFLAGS) -c -DDOUBLE -DCOMPLEX -DNN zgemm_kernel_n_nomacros.s -o $@ - rm zgemm_kernel_n.s zgemm_kernel_n_nomacros.s --else -+else ifeq ($(CORE),SANDYBRIDGE) - $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DDOUBLE -DCOMPLEX -DNN $< -o $@ -+else -+ $(CC) $(CFLAGS) -c -DDOUBLE -DCOMPLEX -DNN $< -o $@ - endif - - $(KDIR)zgemm_kernel_l$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(ZGEMMKERNEL) $(ZGEMMDEPEND) -@@ -828,8 +830,10 @@ ifeq ($(OS), AIX) - m4 zgemm_kernel_l.s > zgemm_kernel_l_nomacros.s - $(CC) $(CFLAGS) -c -DDOUBLE -DCOMPLEX -DCN zgemm_kernel_l_nomacros.s -o $@ - rm zgemm_kernel_l.s zgemm_kernel_l_nomacros.s --else -+else ifeq ($(CORE),SANDYBRIDGE) - $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DDOUBLE -DCOMPLEX -DCN $< -o $@ -+else -+ $(CC) $(CFLAGS) -c -DDOUBLE -DCOMPLEX -DCN $< -o $@ - endif - - $(KDIR)zgemm_kernel_r$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(ZGEMMKERNEL) $(ZGEMMDEPEND) -@@ -838,8 +842,10 @@ ifeq ($(OS), AIX) - m4 zgemm_kernel_r.s > zgemm_kernel_r_nomacros.s - $(CC) $(CFLAGS) -c -DDOUBLE -DCOMPLEX -DNC zgemm_kernel_r_nomacros.s -o $@ - rm zgemm_kernel_r.s zgemm_kernel_r_nomacros.s --else -+else ifeq ($(CORE),SANDYBRIDGE) - $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DDOUBLE -DCOMPLEX -DNC $< -o $@ -+else -+ $(CC) $(CFLAGS) -c -DDOUBLE -DCOMPLEX -DNC $< -o $@ - endif - - $(KDIR)zgemm_kernel_b$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(ZGEMMKERNEL) $(ZGEMMDEPEND) -@@ -848,8 +854,10 @@ ifeq ($(OS), AIX) - m4 zgemm_kernel_b.s > zgemm_kernel_b_nomacros.s - $(CC) $(CFLAGS) -c -DDOUBLE -DCOMPLEX -DCC zgemm_kernel_b_nomacros.s -o $@ - rm zgemm_kernel_b.s zgemm_kernel_b_nomacros.s --else -+else ifeq ($(CORE),SANDYBRIDGE) - $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DDOUBLE -DCOMPLEX -DCC $< -o $@ -+else -+ $(CC) $(CFLAGS) -c -DDOUBLE -DCOMPLEX -DCC $< -o $@ - endif - - $(KDIR)xgemm_kernel_n$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(XGEMMKERNEL) $(XGEMMDEPEND) -@@ -1044,8 +1052,10 @@ ifeq ($(OS), AIX) - m4 ztrmm_kernel_ln.s > ztrmm_kernel_ln_nomacros.s - $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -UTRANSA -UCONJ -DNN ztrmm_kernel_ln_nomacros.s -o $@ - rm ztrmm_kernel_ln.s ztrmm_kernel_ln_nomacros.s --else -+else ifeq ($(CORE), SANDYBRIDGE) - $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -UTRANSA -UCONJ -DNN $< -o $@ -+else -+ $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -UTRANSA -UCONJ -DNN $< -o $@ - endif - - $(KDIR)ztrmm_kernel_LT$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(ZTRMMKERNEL) -@@ -1054,8 +1064,10 @@ ifeq ($(OS), AIX) - m4 ztrmm_kernel_lt.s > ztrmm_kernel_lt_nomacros.s - $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -DTRANSA -UCONJ -DNN ztrmm_kernel_lt_nomacros.s -o $@ - rm ztrmm_kernel_lt.s ztrmm_kernel_lt_nomacros.s --else -+else ifeq ($(CORE), SANDYBRIDGE) - $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -DTRANSA -UCONJ -DNN $< -o $@ -+else -+ $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -DTRANSA -UCONJ -DNN $< -o $@ - endif - - $(KDIR)ztrmm_kernel_LR$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(ZTRMMKERNEL) -@@ -1064,8 +1076,10 @@ ifeq ($(OS), AIX) - m4 ztrmm_kernel_lr.s > ztrmm_kernel_lr_nomacros.s - $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -UTRANSA -DCONJ -DCN ztrmm_kernel_lr_nomacros.s -o $@ - rm ztrmm_kernel_lr.s ztrmm_kernel_lr_nomacros.s --else -+else ifeq ($(CORE), SANDYBRIDGE) - $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -UTRANSA -DCONJ -DCN $< -o $@ -+else -+ $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -UTRANSA -DCONJ -DCN $< -o $@ - endif - - $(KDIR)ztrmm_kernel_LC$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(ZTRMMKERNEL) -@@ -1074,8 +1088,10 @@ ifeq ($(OS), AIX) - m4 ztrmm_kernel_lc.s >ztrmm_kernel_lc_nomacros.s - $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -DTRANSA -DCONJ -DCN ztrmm_kernel_lc_nomacros.s -o $@ - rm ztrmm_kernel_lc.s ztrmm_kernel_lc_nomacros.s --else -+else ifeq ($(CORE), SANDYBRIDGE) - $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -DTRANSA -DCONJ -DCN $< -o $@ -+else -+ $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -DTRANSA -DCONJ -DCN $< -o $@ - endif - - $(KDIR)ztrmm_kernel_RN$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(ZTRMMKERNEL) -@@ -1084,8 +1100,10 @@ ifeq ($(OS), AIX) - m4 ztrmm_kernel_rn.s > ztrmm_kernel_rn_nomacros.s - $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -UTRANSA -UCONJ -DNN ztrmm_kernel_rn_nomacros.s -o $@ - rm ztrmm_kernel_rn.s ztrmm_kernel_rn_nomacros.s --else -+else ifeq ($(CORE), SANDYBRIDGE) - $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -UTRANSA -UCONJ -DNN $< -o $@ -+else -+ $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -UTRANSA -UCONJ -DNN $< -o $@ - endif - - $(KDIR)ztrmm_kernel_RT$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(ZTRMMKERNEL) -@@ -1094,8 +1112,10 @@ ifeq ($(OS), AIX) - m4 ztrmm_kernel_rt.s > ztrmm_kernel_rt_nomacros.s - $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -DTRANSA -UCONJ -DNN ztrmm_kernel_rt_nomacros.s -o $@ - rm ztrmm_kernel_rt.s ztrmm_kernel_rt_nomacros.s --else -+else ifeq ($(CORE), SANDYBRIDGE) - $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -DTRANSA -UCONJ -DNN $< -o $@ -+else -+ $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -DTRANSA -UCONJ -DNN $< -o $@ - endif - - $(KDIR)ztrmm_kernel_RR$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(ZTRMMKERNEL) -@@ -1104,8 +1124,10 @@ ifeq ($(OS), AIX) - m4 ztrmm_kernel_rr.s > ztrmm_kernel_rr_nomacros.s - $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -UTRANSA -DCONJ -DNC ztrmm_kernel_rr_nomacros.s -o $@ - rm ztrmm_kernel_rr.s ztrmm_kernel_rr_nomacros.s --else -+else ifeq ($(CORE), SANDYBRIDGE) - $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -UTRANSA -DCONJ -DNC $< -o $@ -+else -+ $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -UTRANSA -DCONJ -DNC $< -o $@ - endif - - $(KDIR)ztrmm_kernel_RC$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(ZTRMMKERNEL) -@@ -1114,8 +1136,10 @@ ifeq ($(OS), AIX) - m4 ztrmm_kernel_rc.s > ztrmm_kernel_rc_nomacros.s - $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -DTRANSA -DCONJ -DNC ztrmm_kernel_rc_nomacros.s -o $@ - rm ztrmm_kernel_rc.s ztrmm_kernel_rc_nomacros.s --else -+else ifeq ($(CORE), SANDYBRIDGE) - $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -DTRANSA -DCONJ -DNC $< -o $@ -+else -+ $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -DTRANSA -DCONJ -DNC $< -o $@ - endif - - else -@@ -1187,28 +1211,54 @@ $(KDIR)ctrmm_kernel_RC$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(CGEMMKERNEL) - $(CC) $(CFLAGS) -c -DTRMMKERNEL -UDOUBLE -DCOMPLEX -ULEFT -DTRANSA -DCONJ -DNC $< -o $@ - - $(KDIR)ztrmm_kernel_LN$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(ZGEMMKERNEL) -+ifeq ($(CORE),SANDYBRIDGE) - $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -UTRANSA -UCONJ -DNN $< -o $@ -+else -+ $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -UTRANSA -UCONJ -DNN $< -o $@ -+endif - - $(KDIR)ztrmm_kernel_LT$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(ZGEMMKERNEL) -+ifeq ($(CORE),SANDYBRIDGE) - $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -DTRANSA -UCONJ -DNN $< -o $@ -- -+else -+ $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -DTRANSA -UCONJ -DNN $< -o $@ -+endif - $(KDIR)ztrmm_kernel_LR$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(ZGEMMKERNEL) -+ifeq ($(CORE),SANDYBRIDGE) - $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -UTRANSA -DCONJ -DCN $< -o $@ -- -+else -+ $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -UTRANSA -DCONJ -DCN $< -o $@ -+endif - $(KDIR)ztrmm_kernel_LC$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(ZGEMMKERNEL) -+ifeq ($(CORE),SANDYBRIDGE) - $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -DTRANSA -DCONJ -DCN $< -o $@ -- -+else -+ $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -DTRANSA -DCONJ -DCN $< -o $@ -+endif - $(KDIR)ztrmm_kernel_RN$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(ZGEMMKERNEL) -+ifeq ($(CORE),SANDYBRIDGE) - $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -UTRANSA -UCONJ -DNN $< -o $@ -- -+else -+ $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -UTRANSA -UCONJ -DNN $< -o $@ -+endif - $(KDIR)ztrmm_kernel_RT$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(ZGEMMKERNEL) -+ifeq ($(CORE),SANDYBRIDGE) - $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -DTRANSA -UCONJ -DNN $< -o $@ -- -+else -+ $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -DTRANSA -UCONJ -DNN $< -o $@ -+endif - $(KDIR)ztrmm_kernel_RR$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(ZGEMMKERNEL) -+ifeq ($(CORE),SANDYBRIDGE) - $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -UTRANSA -DCONJ -DNC $< -o $@ -- -+else -+ $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -UTRANSA -DCONJ -DNC $< -o $@ -+endif - $(KDIR)ztrmm_kernel_RC$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(ZGEMMKERNEL) -+ifeq ($(CORE),SANDYBRIDGE) - $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -DTRANSA -DCONJ -DNC $< -o $@ -+else -+ $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -DTRANSA -DCONJ -DNC $< -o $@ -+endif - endif - - --- -2.31.1 - diff --git a/deps/patches/openblas-armv8-volatile-detecion.patch b/deps/patches/openblas-armv8-volatile-detecion.patch deleted file mode 100644 index f1fb36b6a34ab4..00000000000000 --- a/deps/patches/openblas-armv8-volatile-detecion.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 6fe0f1fab9d6a7f46d71d37ebb210fbf56924fbc Mon Sep 17 00:00:00 2001 -From: Martin Kroeker -Date: Mon, 11 Jan 2021 19:05:29 +0100 -Subject: [PATCH] Label get_cpu_ftr as volatile to keep gcc from rearranging - the code - ---- - driver/others/dynamic_arm64.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/driver/others/dynamic_arm64.c b/driver/others/dynamic_arm64.c -index 4f1b12f27a..37c0694b6f 100644 ---- a/driver/others/dynamic_arm64.c -+++ b/driver/others/dynamic_arm64.c -@@ -68,7 +68,7 @@ extern void openblas_warning(int verbose, const char * msg); - #endif - - #define get_cpu_ftr(id, var) ({ \ -- __asm__("mrs %0, "#id : "=r" (var)); \ -+ __asm__ __volatile__("mrs %0, "#id : "=r" (var)); \ - }) - - static char *corename[] = { diff --git a/deps/patches/openblas-exshift.patch b/deps/patches/openblas-exshift.patch deleted file mode 100644 index 4a0016ef662520..00000000000000 --- a/deps/patches/openblas-exshift.patch +++ /dev/null @@ -1,149 +0,0 @@ -commit c4b5abbe43d7c22215ef36ef4f7c1413c975678c -Author: Martin Kroeker -Date: Fri Jan 29 10:45:36 2021 +0100 - - fix data type - -commit f87842483eee9d158f44d51d4c09662c3cff7526 -Author: Martin Kroeker -Date: Fri Jan 29 09:56:12 2021 +0100 - - fix calculation of non-exceptional shift (from Reference-LAPACK PR 477) - -commit 856bc365338f7559639f341d76ca8746d1628ee5 -Author: Martin Kroeker -Date: Wed Jan 27 13:41:45 2021 +0100 - - Add exceptional shift to fix rare convergence problems - ---- -diff --git a/lapack-netlib/SRC/chgeqz.f b/lapack-netlib/SRC/chgeqz.f -index 73d35621..4725e716 100644 ---- a/lapack-netlib/SRC/chgeqz.f -+++ b/lapack-netlib/SRC/chgeqz.f -@@ -320,12 +320,13 @@ - $ C, SAFMIN, TEMP, TEMP2, TEMPR, ULP - COMPLEX ABI22, AD11, AD12, AD21, AD22, CTEMP, CTEMP2, - $ CTEMP3, ESHIFT, RTDISC, S, SHIFT, SIGNBC, T1, -- $ U12, X -+ $ U12, X, ABI12, Y - * .. - * .. External Functions .. -+ COMPLEX CLADIV - LOGICAL LSAME - REAL CLANHS, SLAMCH -- EXTERNAL LSAME, CLANHS, SLAMCH -+ EXTERNAL CLADIV, LLSAME, CLANHS, SLAMCH - * .. - * .. External Subroutines .. - EXTERNAL CLARTG, CLASET, CROT, CSCAL, XERBLA -@@ -729,22 +730,34 @@ - AD22 = ( ASCALE*H( ILAST, ILAST ) ) / - $ ( BSCALE*T( ILAST, ILAST ) ) - ABI22 = AD22 - U12*AD21 -+ ABI12 = AD12 - U12*AD11 - * -- T1 = HALF*( AD11+ABI22 ) -- RTDISC = SQRT( T1**2+AD12*AD21-AD11*AD22 ) -- TEMP = REAL( T1-ABI22 )*REAL( RTDISC ) + -- $ AIMAG( T1-ABI22 )*AIMAG( RTDISC ) -- IF( TEMP.LE.ZERO ) THEN -- SHIFT = T1 + RTDISC -- ELSE -- SHIFT = T1 - RTDISC -+ SHIFT = ABI22 -+ CTEMP = SQRT( ABI12 )*SQRT( AD21 ) -+ TEMP = ABS1( CTEMP ) -+ IF( CTEMP.NE.ZERO ) THEN -+ X = HALF*( AD11-SHIFT ) -+ TEMP2 = ABS1( X ) -+ TEMP = MAX( TEMP, ABS1( X ) ) -+ Y = TEMP*SQRT( ( X / TEMP )**2+( CTEMP / TEMP )**2 ) -+ IF( TEMP2.GT.ZERO ) THEN -+ IF( REAL( X / TEMP2 )*REAL( Y )+ -+ $ AIMAG( X / TEMP2 )*AIMAG( Y ).LT.ZERO )Y = -Y -+ END IF -+ SHIFT = SHIFT - CTEMP*CLADIV( CTEMP, ( X+Y ) ) - END IF - ELSE - * - * Exceptional shift. Chosen for no particularly good reason. - * -- ESHIFT = ESHIFT + (ASCALE*H(ILAST,ILAST-1))/ -- $ (BSCALE*T(ILAST-1,ILAST-1)) -+ IF( ( IITER / 20 )*20.EQ.IITER .AND. -+ $ BSCALE*ABS1(T( ILAST, ILAST )).GT.SAFMIN ) THEN -+ ESHIFT = ESHIFT + ( ASCALE*H( ILAST, -+ $ ILAST ) )/( BSCALE*T( ILAST, ILAST ) ) -+ ELSE -+ ESHIFT = ESHIFT + ( ASCALE*H( ILAST, -+ $ ILAST-1 ) )/( BSCALE*T( ILAST-1, ILAST-1 ) ) -+ END IF - SHIFT = ESHIFT - END IF - * -diff --git a/lapack-netlib/SRC/zhgeqz.f b/lapack-netlib/SRC/zhgeqz.f -index b51cba4f..b28ae47a 100644 ---- a/lapack-netlib/SRC/zhgeqz.f -+++ b/lapack-netlib/SRC/zhgeqz.f -@@ -320,12 +320,13 @@ - $ C, SAFMIN, TEMP, TEMP2, TEMPR, ULP - COMPLEX*16 ABI22, AD11, AD12, AD21, AD22, CTEMP, CTEMP2, - $ CTEMP3, ESHIFT, RTDISC, S, SHIFT, SIGNBC, T1, -- $ U12, X -+ $ U12, X, ABI12, Y - * .. - * .. External Functions .. -+ COMPLEX*16 ZLADIV - LOGICAL LSAME - DOUBLE PRECISION DLAMCH, ZLANHS -- EXTERNAL LSAME, DLAMCH, ZLANHS -+ EXTERNAL ZLADIV, LSAME, DLAMCH, ZLANHS - * .. - * .. External Subroutines .. - EXTERNAL XERBLA, ZLARTG, ZLASET, ZROT, ZSCAL -@@ -730,22 +731,34 @@ - AD22 = ( ASCALE*H( ILAST, ILAST ) ) / - $ ( BSCALE*T( ILAST, ILAST ) ) - ABI22 = AD22 - U12*AD21 -+ ABI12 = AD12 - U12*AD11 - * -- T1 = HALF*( AD11+ABI22 ) -- RTDISC = SQRT( T1**2+AD12*AD21-AD11*AD22 ) -- TEMP = DBLE( T1-ABI22 )*DBLE( RTDISC ) + -- $ DIMAG( T1-ABI22 )*DIMAG( RTDISC ) -- IF( TEMP.LE.ZERO ) THEN -- SHIFT = T1 + RTDISC -- ELSE -- SHIFT = T1 - RTDISC -+ SHIFT = ABI22 -+ CTEMP = SQRT( ABI12 )*SQRT( AD21 ) -+ TEMP = ABS1( CTEMP ) -+ IF( CTEMP.NE.ZERO ) THEN -+ X = HALF*( AD11-SHIFT ) -+ TEMP2 = ABS1( X ) -+ TEMP = MAX( TEMP, ABS1( X ) ) -+ Y = TEMP*SQRT( ( X / TEMP )**2+( CTEMP / TEMP )**2 ) -+ IF( TEMP2.GT.ZERO ) THEN -+ IF( DBLE( X / TEMP2 )*DBLE( Y )+ -+ $ DIMAG( X / TEMP2 )*DIMAG( Y ).LT.ZERO )Y = -Y -+ END IF -+ SHIFT = SHIFT - CTEMP*ZLADIV( CTEMP, ( X+Y ) ) - END IF - ELSE - * - * Exceptional shift. Chosen for no particularly good reason. - * -- ESHIFT = ESHIFT + (ASCALE*H(ILAST,ILAST-1))/ -- $ (BSCALE*T(ILAST-1,ILAST-1)) -+ IF( ( IITER / 20 )*20.EQ.IITER .AND. -+ $ BSCALE*ABS1(T( ILAST, ILAST )).GT.SAFMIN ) THEN -+ ESHIFT = ESHIFT + ( ASCALE*H( ILAST, -+ $ ILAST ) )/( BSCALE*T( ILAST, ILAST ) ) -+ ELSE -+ ESHIFT = ESHIFT + ( ASCALE*H( ILAST, -+ $ ILAST-1 ) )/( BSCALE*T( ILAST-1, ILAST-1 ) ) -+ END IF - SHIFT = ESHIFT - END IF - * diff --git a/deps/patches/openblas-filter-out-mavx-flag-on-zgemm-kernels.patch b/deps/patches/openblas-filter-out-mavx-flag-on-zgemm-kernels.patch deleted file mode 100644 index 5c9fa4aaa59e94..00000000000000 --- a/deps/patches/openblas-filter-out-mavx-flag-on-zgemm-kernels.patch +++ /dev/null @@ -1,162 +0,0 @@ -From bd60fb6ffc9d14834ed03bed0f7e6e44126c6c05 Mon Sep 17 00:00:00 2001 -From: Martin Kroeker -Date: Thu, 13 May 2021 23:05:00 +0200 -Subject: [PATCH 1/2] filter out -mavx flag on zgemm kernels as it can cause - problems with older gcc - ---- - kernel/Makefile.L3 | 40 ++++++++++++++++++++-------------------- - 1 file changed, 20 insertions(+), 20 deletions(-) - -diff --git a/kernel/Makefile.L3 b/kernel/Makefile.L3 -index d8d73996..be10ee01 100644 ---- a/kernel/Makefile.L3 -+++ b/kernel/Makefile.L3 -@@ -819,7 +819,7 @@ ifeq ($(OS), AIX) - $(CC) $(CFLAGS) -c -DDOUBLE -DCOMPLEX -DNN zgemm_kernel_n_nomacros.s -o $@ - rm zgemm_kernel_n.s zgemm_kernel_n_nomacros.s - else -- $(CC) $(CFLAGS) -c -DDOUBLE -DCOMPLEX -DNN $< -o $@ -+ $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DDOUBLE -DCOMPLEX -DNN $< -o $@ - endif - - $(KDIR)zgemm_kernel_l$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(ZGEMMKERNEL) $(ZGEMMDEPEND) -@@ -829,7 +829,7 @@ ifeq ($(OS), AIX) - $(CC) $(CFLAGS) -c -DDOUBLE -DCOMPLEX -DCN zgemm_kernel_l_nomacros.s -o $@ - rm zgemm_kernel_l.s zgemm_kernel_l_nomacros.s - else -- $(CC) $(CFLAGS) -c -DDOUBLE -DCOMPLEX -DCN $< -o $@ -+ $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DDOUBLE -DCOMPLEX -DCN $< -o $@ - endif - - $(KDIR)zgemm_kernel_r$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(ZGEMMKERNEL) $(ZGEMMDEPEND) -@@ -839,7 +839,7 @@ ifeq ($(OS), AIX) - $(CC) $(CFLAGS) -c -DDOUBLE -DCOMPLEX -DNC zgemm_kernel_r_nomacros.s -o $@ - rm zgemm_kernel_r.s zgemm_kernel_r_nomacros.s - else -- $(CC) $(CFLAGS) -c -DDOUBLE -DCOMPLEX -DNC $< -o $@ -+ $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DDOUBLE -DCOMPLEX -DNC $< -o $@ - endif - - $(KDIR)zgemm_kernel_b$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(ZGEMMKERNEL) $(ZGEMMDEPEND) -@@ -849,7 +849,7 @@ ifeq ($(OS), AIX) - $(CC) $(CFLAGS) -c -DDOUBLE -DCOMPLEX -DCC zgemm_kernel_b_nomacros.s -o $@ - rm zgemm_kernel_b.s zgemm_kernel_b_nomacros.s - else -- $(CC) $(CFLAGS) -c -DDOUBLE -DCOMPLEX -DCC $< -o $@ -+ $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DDOUBLE -DCOMPLEX -DCC $< -o $@ - endif - - $(KDIR)xgemm_kernel_n$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(XGEMMKERNEL) $(XGEMMDEPEND) -@@ -1045,7 +1045,7 @@ ifeq ($(OS), AIX) - $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -UTRANSA -UCONJ -DNN ztrmm_kernel_ln_nomacros.s -o $@ - rm ztrmm_kernel_ln.s ztrmm_kernel_ln_nomacros.s - else -- $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -UTRANSA -UCONJ -DNN $< -o $@ -+ $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -UTRANSA -UCONJ -DNN $< -o $@ - endif - - $(KDIR)ztrmm_kernel_LT$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(ZTRMMKERNEL) -@@ -1055,7 +1055,7 @@ ifeq ($(OS), AIX) - $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -DTRANSA -UCONJ -DNN ztrmm_kernel_lt_nomacros.s -o $@ - rm ztrmm_kernel_lt.s ztrmm_kernel_lt_nomacros.s - else -- $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -DTRANSA -UCONJ -DNN $< -o $@ -+ $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -DTRANSA -UCONJ -DNN $< -o $@ - endif - - $(KDIR)ztrmm_kernel_LR$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(ZTRMMKERNEL) -@@ -1065,7 +1065,7 @@ ifeq ($(OS), AIX) - $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -UTRANSA -DCONJ -DCN ztrmm_kernel_lr_nomacros.s -o $@ - rm ztrmm_kernel_lr.s ztrmm_kernel_lr_nomacros.s - else -- $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -UTRANSA -DCONJ -DCN $< -o $@ -+ $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -UTRANSA -DCONJ -DCN $< -o $@ - endif - - $(KDIR)ztrmm_kernel_LC$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(ZTRMMKERNEL) -@@ -1075,7 +1075,7 @@ ifeq ($(OS), AIX) - $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -DTRANSA -DCONJ -DCN ztrmm_kernel_lc_nomacros.s -o $@ - rm ztrmm_kernel_lc.s ztrmm_kernel_lc_nomacros.s - else -- $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -DTRANSA -DCONJ -DCN $< -o $@ -+ $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -DTRANSA -DCONJ -DCN $< -o $@ - endif - - $(KDIR)ztrmm_kernel_RN$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(ZTRMMKERNEL) -@@ -1085,7 +1085,7 @@ ifeq ($(OS), AIX) - $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -UTRANSA -UCONJ -DNN ztrmm_kernel_rn_nomacros.s -o $@ - rm ztrmm_kernel_rn.s ztrmm_kernel_rn_nomacros.s - else -- $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -UTRANSA -UCONJ -DNN $< -o $@ -+ $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -UTRANSA -UCONJ -DNN $< -o $@ - endif - - $(KDIR)ztrmm_kernel_RT$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(ZTRMMKERNEL) -@@ -1095,7 +1095,7 @@ ifeq ($(OS), AIX) - $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -DTRANSA -UCONJ -DNN ztrmm_kernel_rt_nomacros.s -o $@ - rm ztrmm_kernel_rt.s ztrmm_kernel_rt_nomacros.s - else -- $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -DTRANSA -UCONJ -DNN $< -o $@ -+ $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -DTRANSA -UCONJ -DNN $< -o $@ - endif - - $(KDIR)ztrmm_kernel_RR$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(ZTRMMKERNEL) -@@ -1105,7 +1105,7 @@ ifeq ($(OS), AIX) - $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -UTRANSA -DCONJ -DNC ztrmm_kernel_rr_nomacros.s -o $@ - rm ztrmm_kernel_rr.s ztrmm_kernel_rr_nomacros.s - else -- $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -UTRANSA -DCONJ -DNC $< -o $@ -+ $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -UTRANSA -DCONJ -DNC $< -o $@ - endif - - $(KDIR)ztrmm_kernel_RC$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(ZTRMMKERNEL) -@@ -1115,7 +1115,7 @@ ifeq ($(OS), AIX) - $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -DTRANSA -DCONJ -DNC ztrmm_kernel_rc_nomacros.s -o $@ - rm ztrmm_kernel_rc.s ztrmm_kernel_rc_nomacros.s - else -- $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -DTRANSA -DCONJ -DNC $< -o $@ -+ $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -DTRANSA -DCONJ -DNC $< -o $@ - endif - - else -@@ -1187,28 +1187,28 @@ $(KDIR)ctrmm_kernel_RC$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(CGEMMKERNEL) - $(CC) $(CFLAGS) -c -DTRMMKERNEL -UDOUBLE -DCOMPLEX -ULEFT -DTRANSA -DCONJ -DNC $< -o $@ - - $(KDIR)ztrmm_kernel_LN$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(ZGEMMKERNEL) -- $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -UTRANSA -UCONJ -DNN $< -o $@ -+ $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -UTRANSA -UCONJ -DNN $< -o $@ - - $(KDIR)ztrmm_kernel_LT$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(ZGEMMKERNEL) -- $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -DTRANSA -UCONJ -DNN $< -o $@ -+ $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -DTRANSA -UCONJ -DNN $< -o $@ - - $(KDIR)ztrmm_kernel_LR$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(ZGEMMKERNEL) -- $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -UTRANSA -DCONJ -DCN $< -o $@ -+ $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -UTRANSA -DCONJ -DCN $< -o $@ - - $(KDIR)ztrmm_kernel_LC$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(ZGEMMKERNEL) -- $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -DTRANSA -DCONJ -DCN $< -o $@ -+ $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -DLEFT -DTRANSA -DCONJ -DCN $< -o $@ - - $(KDIR)ztrmm_kernel_RN$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(ZGEMMKERNEL) -- $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -UTRANSA -UCONJ -DNN $< -o $@ -+ $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -UTRANSA -UCONJ -DNN $< -o $@ - - $(KDIR)ztrmm_kernel_RT$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(ZGEMMKERNEL) -- $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -DTRANSA -UCONJ -DNN $< -o $@ -+ $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -DTRANSA -UCONJ -DNN $< -o $@ - - $(KDIR)ztrmm_kernel_RR$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(ZGEMMKERNEL) -- $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -UTRANSA -DCONJ -DNC $< -o $@ -+ $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -UTRANSA -DCONJ -DNC $< -o $@ - - $(KDIR)ztrmm_kernel_RC$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(ZGEMMKERNEL) -- $(CC) $(CFLAGS) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -DTRANSA -DCONJ -DNC $< -o $@ -+ $(CC) $(filter-out -mavx,$(CFLAGS)) -c -DTRMMKERNEL -DDOUBLE -DCOMPLEX -ULEFT -DTRANSA -DCONJ -DNC $< -o $@ - endif - - --- -2.31.1 - diff --git a/deps/patches/openblas-ofast-power.patch b/deps/patches/openblas-ofast-power.patch index 2bb01c9b08115d..c741496cae757c 100644 --- a/deps/patches/openblas-ofast-power.patch +++ b/deps/patches/openblas-ofast-power.patch @@ -1,19 +1,17 @@ - Makefile.power | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - diff --git a/Makefile.power b/Makefile.power -index c7e97229..8426e816 100644 +index 946f5523..19593050 100644 --- a/Makefile.power +++ b/Makefile.power -@@ -10,13 +10,13 @@ USE_OPENMP = 1 - endif - +@@ -11,14 +11,14 @@ endif + ifeq ($(CORE), POWER10) + ifneq ($(C_COMPILER), PGI) -CCOMMON_OPT += -Ofast -mcpu=power10 -mtune=power10 -mvsx -fno-fast-math +CCOMMON_OPT += -mcpu=power10 -mtune=power10 -mvsx -fno-fast-math FCOMMON_OPT += -O2 -frecursive -mcpu=power10 -mtune=power10 -fno-fast-math endif - + endif + ifeq ($(CORE), POWER9) ifneq ($(C_COMPILER), PGI) -CCOMMON_OPT += -Ofast -mvsx -fno-fast-math @@ -21,8 +19,8 @@ index c7e97229..8426e816 100644 ifeq ($(C_COMPILER), GCC) ifneq ($(GCCVERSIONGT4), 1) $(warning your compiler is too old to fully support POWER9, getting a newer version of gcc is recommended) -@@ -49,7 +49,7 @@ endif - +@@ -51,7 +51,7 @@ endif + ifeq ($(CORE), POWER8) ifneq ($(C_COMPILER), PGI) -CCOMMON_OPT += -Ofast -mcpu=power8 -mtune=power8 -mvsx -fno-fast-math diff --git a/deps/patches/openblas-winexit.patch b/deps/patches/openblas-winexit.patch index 01085102f331a2..33389f34a40742 100644 --- a/deps/patches/openblas-winexit.patch +++ b/deps/patches/openblas-winexit.patch @@ -1,13 +1,5 @@ -From f919c3301fabbaa5d965dcc7b1c3d6892a8c730a Mon Sep 17 00:00:00 2001 -From: Keno Fischer -Date: Sat, 14 Mar 2020 12:05:19 +0100 - ---- - driver/others/memory.c | 131 +------------------------------------------------ - 1 file changed, 2 insertions(+), 129 deletions(-) - diff --git a/driver/others/memory.c b/driver/others/memory.c -index ba2bb55b..bf6b5529 100644 +index 6e654ccf..1d2f9f12 100644 --- a/driver/others/memory.c +++ b/driver/others/memory.c @@ -1534,7 +1534,7 @@ void CONSTRUCTOR gotoblas_init(void) { @@ -19,11 +11,10 @@ index ba2bb55b..bf6b5529 100644 if (gotoblas_initialized == 0) return; -@@ -1571,74 +1571,12 @@ void DESTRUCTOR gotoblas_quit(void) { - #endif +@@ -1572,75 +1572,11 @@ void DESTRUCTOR gotoblas_quit(void) { } --#if defined(_MSC_VER) && !defined(__clang__) + #if defined(_MSC_VER) && !defined(__clang__) -BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) -{ - switch (ul_reason_for_call) @@ -65,16 +56,18 @@ index ba2bb55b..bf6b5529 100644 #else #pragma comment(linker, "/INCLUDE:__tls_used") #endif - +- -#ifdef _WIN64 -#pragma const_seg(".CRT$XLB") -#else -#pragma data_seg(".CRT$XLB") -#endif --static void (APIENTRY *dll_callback)(HINSTANCE h, DWORD ul_reason_for_call, PVOID pv) = DllMain; +- -#ifdef _WIN64 +-static const PIMAGE_TLS_CALLBACK dll_callback(HINSTANCE h, DWORD ul_reason_for_call, PVOID pv) = DllMain; -#pragma const_seg() -#else +-static void (APIENTRY *dll_callback)(HINSTANCE h, DWORD ul_reason_for_call, PVOID pv) = DllMain; -#pragma data_seg() -#endif - @@ -83,18 +76,18 @@ index ba2bb55b..bf6b5529 100644 -#else -#pragma data_seg(".CRT$XTU") -#endif --static int(*p_process_term)(void) = on_process_term; +- -#ifdef _WIN64 +-static const int(*p_process_term)(void) = on_process_term; -#pragma const_seg() -#else +-static int(*p_process_term)(void) = on_process_term; -#pragma data_seg() -#endif --#endif -- + #endif + #if (defined(C_PGI) || (!defined(C_SUN) && defined(F_INTERFACE_SUN))) && (defined(ARCH_X86) || defined(ARCH_X86_64)) - /* Don't call me; this is just work around for PGI / Sun bug */ - void gotoblas_dummy_for_PGI(void) { -@@ -3136,7 +3074,7 @@ void CONSTRUCTOR gotoblas_init(void) { +@@ -3146,7 +3082,7 @@ void CONSTRUCTOR gotoblas_init(void) { } @@ -103,7 +96,7 @@ index ba2bb55b..bf6b5529 100644 if (gotoblas_initialized == 0) return; -@@ -3165,71 +3103,6 @@ void DESTRUCTOR gotoblas_quit(void) { +@@ -3175,71 +3111,6 @@ void DESTRUCTOR gotoblas_quit(void) { #endif } diff --git a/stdlib/LinearAlgebra/src/LinearAlgebra.jl b/stdlib/LinearAlgebra/src/LinearAlgebra.jl index f0f13776146d1a..4ac4a142caf073 100644 --- a/stdlib/LinearAlgebra/src/LinearAlgebra.jl +++ b/stdlib/LinearAlgebra/src/LinearAlgebra.jl @@ -291,14 +291,14 @@ julia> ldiv!(Y, qr(A), X); julia> Y 3-element Vector{Float64}: 0.7128099173553719 - -0.051652892561983806 - 0.10020661157024781 + -0.051652892561983674 + 0.10020661157024757 julia> A\\X 3-element Vector{Float64}: 0.7128099173553719 - -0.05165289256198342 - 0.1002066115702479 + -0.05165289256198333 + 0.10020661157024785 ``` """ ldiv!(Y, A, B) @@ -328,14 +328,14 @@ julia> ldiv!(qr(A), X); julia> X 3-element Vector{Float64}: 0.7128099173553719 - -0.051652892561983806 - 0.10020661157024781 + -0.051652892561983674 + 0.10020661157024757 julia> A\\Y 3-element Vector{Float64}: 0.7128099173553719 - -0.05165289256198342 - 0.1002066115702479 + -0.05165289256198333 + 0.10020661157024785 ``` """ ldiv!(A, B) diff --git a/stdlib/LinearAlgebra/src/hessenberg.jl b/stdlib/LinearAlgebra/src/hessenberg.jl index 9a864da2b0a379..e79786da925aa9 100644 --- a/stdlib/LinearAlgebra/src/hessenberg.jl +++ b/stdlib/LinearAlgebra/src/hessenberg.jl @@ -483,9 +483,9 @@ Q factor: 0.0 -0.707107 0.707107 H factor: 3×3 UpperHessenberg{Float64, Matrix{Float64}}: - 4.0 -11.3137 -1.41421 - -5.65685 5.0 2.0 - ⋅ -1.0444e-15 1.0 + 4.0 -11.3137 -1.41421 + -5.65685 5.0 2.0 + ⋅ -8.88178e-16 1.0 julia> F.Q * F.H * F.Q' 3×3 Matrix{Float64}: diff --git a/stdlib/OpenBLAS_jll/Project.toml b/stdlib/OpenBLAS_jll/Project.toml index 4be6814c6632ef..c7d59bb0328974 100644 --- a/stdlib/OpenBLAS_jll/Project.toml +++ b/stdlib/OpenBLAS_jll/Project.toml @@ -1,6 +1,6 @@ name = "OpenBLAS_jll" uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" -version = "0.3.13+7" +version = "0.3.17+0" [deps] CompilerSupportLibraries_jll = "e66e0078-7015-5450-92f7-15fbd957f2ae" From bb8e77e98e5a04ad9711cde79a7cda699f3b1372 Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Wed, 25 Aug 2021 01:57:13 +0400 Subject: [PATCH 110/135] Update tag to v1.6.2 in readme (#41989) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 770acbfea20512..8a7a59ce73a576 100644 --- a/README.md +++ b/README.md @@ -101,7 +101,7 @@ Julia. However, most users should use the most recent stable version of Julia. You can get this version by changing to the Julia directory and running: - git checkout v1.6.1 + git checkout v1.6.2 Now run `make` to build the `julia` executable. From 8364a4ccd8885fa8d8c78094c7653c58e33d9f0d Mon Sep 17 00:00:00 2001 From: Jakob Nybo Nissen Date: Wed, 25 Aug 2021 00:42:41 +0200 Subject: [PATCH 111/135] Fix collect on stateful generator (#41919) Previously this code would drop 1 from the length of some generators. Fixes #35530 --- base/array.jl | 10 +++++++--- test/iterators.jl | 11 ++++++++++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/base/array.jl b/base/array.jl index b09a7bd4de836b..af75094460e4c4 100644 --- a/base/array.jl +++ b/base/array.jl @@ -758,8 +758,10 @@ else end end -_array_for(::Type{T}, itr, ::HasLength) where {T} = Vector{T}(undef, Int(length(itr)::Integer)) -_array_for(::Type{T}, itr, ::HasShape{N}) where {T,N} = similar(Array{T,N}, axes(itr)) +_array_for(::Type{T}, itr, isz::HasLength) where {T} = _array_for(T, itr, isz, length(itr)) +_array_for(::Type{T}, itr, isz::HasShape{N}) where {T,N} = _array_for(T, itr, isz, axes(itr)) +_array_for(::Type{T}, itr, ::HasLength, len) where {T} = Vector{T}(undef, len) +_array_for(::Type{T}, itr, ::HasShape{N}, axs) where {T,N} = similar(Array{T,N}, axs) function collect(itr::Generator) isz = IteratorSize(itr.iter) @@ -767,12 +769,14 @@ function collect(itr::Generator) if isa(isz, SizeUnknown) return grow_to!(Vector{et}(), itr) else + shape = isz isa HasLength ? length(itr) : axes(itr) y = iterate(itr) if y === nothing return _array_for(et, itr.iter, isz) end v1, st = y - collect_to_with_first!(_array_for(typeof(v1), itr.iter, isz), v1, itr, st) + arr = _array_for(typeof(v1), itr.iter, isz, shape) + return collect_to_with_first!(arr, v1, itr, st) end end diff --git a/test/iterators.jl b/test/iterators.jl index fb8edcab922099..c7d00c4e7e2e83 100644 --- a/test/iterators.jl +++ b/test/iterators.jl @@ -292,6 +292,15 @@ let (a, b) = (1:3, [4 6; end end +# collect stateful iterator +let + itr = (i+1 for i in Base.Stateful([1,2,3])) + @test collect(itr) == [2, 3, 4] + A = zeros(Int, 0, 0) + itr = (i-1 for i in Base.Stateful(A)) + @test collect(itr) == Int[] # Stateful do not preserve shape +end + # with 1D inputs let a = 1:2, b = 1.0:10.0, @@ -860,4 +869,4 @@ end @test Iterators.peel(1:10)[2] |> collect == 2:10 @test Iterators.peel(x^2 for x in 2:4)[1] == 4 @test Iterators.peel(x^2 for x in 2:4)[2] |> collect == [9, 16] -end \ No newline at end of file +end From 9955360571e5b68f793a78ce9f98ac14bafd446e Mon Sep 17 00:00:00 2001 From: Xuanda Yang Date: Wed, 25 Aug 2021 07:01:26 +0800 Subject: [PATCH 112/135] doc: internal IR representation of undefcheck and foreigncall (#41780) Previously we had an inclusive range that expressed one too many elements. Fixes #41636 --- doc/src/devdocs/ast.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/doc/src/devdocs/ast.md b/doc/src/devdocs/ast.md index 8a2c93e71ced86..187c93d7f61e92 100644 --- a/doc/src/devdocs/ast.md +++ b/doc/src/devdocs/ast.md @@ -438,6 +438,10 @@ These symbols appear in the `head` field of [`Expr`](@ref)s in lowered form. Yields the caught exception inside a `catch` block, as returned by `jl_current_exception()`. + * `undefcheck` + + Temporary node inserted by the compiler and will be processed in `type_lift_pass!`. + * `enter` Enters an exception handler (`setjmp`). `args[1]` is the label of the catch block to jump to on @@ -507,11 +511,11 @@ These symbols appear in the `head` field of [`Expr`](@ref)s in lowered form. The calling convention for the call. - * `args[6:6+length(args[3])]` : arguments + * `args[6:5+length(args[3])]` : arguments The values for all the arguments (with types of each given in args[3]). - * `args[6+(length(args[3])+1):end]` : gc-roots + * `args[6+length(args[3])+1:end]` : gc-roots The additional objects that may need to be gc-rooted for the duration of the call. See [Working with LLVM](@ref Working-with-LLVM) for where these are derived from and how they get handled. From 47c5d628d1e94a2e0ffdacfbd8f75c84065fe0a2 Mon Sep 17 00:00:00 2001 From: V3 Date: Wed, 25 Aug 2021 01:48:00 +0200 Subject: [PATCH 113/135] fixed static linking of libllvm (#41276) --- src/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Makefile b/src/Makefile index 25e8d931d83c9a..fe5fc81328d1aa 100644 --- a/src/Makefile +++ b/src/Makefile @@ -113,7 +113,7 @@ LLVMLINK += $(LLVM_LDFLAGS) $(shell $(LLVM_CONFIG_HOST) --libs --system-libs) # https://github.com/JuliaLang/julia/issues/29981 else ifneq ($(USE_LLVM_SHLIB),1) -LLVMLINK += $(LLVM_LDFLAGS) $(shell $(LLVM_CONFIG_HOST) --libs $(LLVM_LIBS)) $($(LLVM_LDFLAGS) $(shell $(LLVM_CONFIG_HOST) --system-libs 2> /dev/null) +LLVMLINK += $(LLVM_LDFLAGS) $(shell $(LLVM_CONFIG_HOST) --libs $(LLVM_LIBS) --link-static) $($(LLVM_LDFLAGS) $(shell $(LLVM_CONFIG_HOST) --system-libs 2> /dev/null) else LLVMLINK += $(LLVM_LDFLAGS) -lLLVM endif @@ -230,7 +230,7 @@ endif $(INSTALL_NAME_CMD)libccalltest.$(SHLIB_EXT) $@ $(build_shlibdir)/libllvmcalltest.$(SHLIB_EXT): $(SRCDIR)/llvmcalltest.cpp $(LLVM_CONFIG_ABSOLUTE) - @$(call PRINT_CC, $(CXX) $(LLVM_CXXFLAGS) $(JCXXFLAGS) $(JCPPFLAGS) $(DEBUGFLAGS) -O3 $< $(fPIC) -shared -o $@ $(JLDFLAGS) -L$(build_shlibdir) -L$(build_libdir) $(NO_WHOLE_ARCHIVE) $(LLVMLINK)) + @$(call PRINT_CC, $(CXX) $(LLVM_CXXFLAGS) $(JCXXFLAGS) $(JCPPFLAGS) $(DEBUGFLAGS) -O3 $< $(fPIC) -shared -o $@ $(JLDFLAGS) -L$(build_shlibdir) -L$(build_libdir) $(NO_WHOLE_ARCHIVE) $(LLVMLINK)) -lpthread julia_flisp.boot.inc.phony: $(BUILDDIR)/julia_flisp.boot.inc From 7a784de2bf4df9e931fa868b22231df9cdb01801 Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Tue, 24 Aug 2021 20:50:27 -0400 Subject: [PATCH 114/135] fix a case where Vararg.T might be accessed when undefined (#41867) --- base/compiler/typelimits.jl | 2 +- test/compiler/inference.jl | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/base/compiler/typelimits.jl b/base/compiler/typelimits.jl index 3145517630958c..23045c65cc6bbb 100644 --- a/base/compiler/typelimits.jl +++ b/base/compiler/typelimits.jl @@ -130,7 +130,7 @@ function _limit_type_size(@nospecialize(t), @nospecialize(c), sources::SimpleVec elseif isa(t, DataType) if isa(c, Core.TypeofVararg) # Tuple{Vararg{T}} --> Tuple{T} is OK - return _limit_type_size(t, c.T, sources, depth, 0) + return _limit_type_size(t, unwrapva(c), sources, depth, 0) elseif isType(t) # allow taking typeof as Type{...}, but ensure it doesn't start nesting tt = unwrap_unionall(t.parameters[1]) (!isa(tt, DataType) || isType(tt)) && (depth += 1) diff --git a/test/compiler/inference.jl b/test/compiler/inference.jl index 1e61cc9e440946..a5f83160ee7e23 100644 --- a/test/compiler/inference.jl +++ b/test/compiler/inference.jl @@ -44,6 +44,11 @@ let t = Tuple{Ref{T},T,T} where T, c = Tuple{Ref, T, T} where T # #36407 @test t <: Core.Compiler.limit_type_size(t, c, Union{}, 1, 100) end +# obtain Vararg with 2 undefined fields +let va = ccall(:jl_type_intersection_with_env, Any, (Any, Any), Tuple{Tuple}, Tuple{Tuple{Vararg{Any, N}}} where N)[2][1] + @test Core.Compiler.limit_type_size(Tuple, va, Union{}, 2, 2) === Any +end + let # 40336 t = Type{Type{Int}} c = Type{Int} From e2aeefb60eaffbd2807089155789e19585f4e6fe Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Tue, 24 Aug 2021 22:27:10 -0400 Subject: [PATCH 115/135] fix #41908, inference error in subst_trivial_bounds (#41976) Co-authored-by: Martin Holters --- base/compiler/utilities.jl | 10 +++++++++- test/compiler/inference.jl | 5 +++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/base/compiler/utilities.jl b/base/compiler/utilities.jl index 5d4d52172a300a..ed09d5316473a4 100644 --- a/base/compiler/utilities.jl +++ b/base/compiler/utilities.jl @@ -156,7 +156,15 @@ function subst_trivial_bounds(@nospecialize(atypes)) end v = atypes.var if isconcretetype(v.ub) || v.lb === v.ub - return subst_trivial_bounds(atypes{v.ub}) + subst = try + atypes{v.ub} + catch + # Note in rare cases a var bound might not be valid to substitute. + nothing + end + if subst !== nothing + return subst_trivial_bounds(subst) + end end return UnionAll(v, subst_trivial_bounds(atypes.body)) end diff --git a/test/compiler/inference.jl b/test/compiler/inference.jl index a5f83160ee7e23..4890329f1a3751 100644 --- a/test/compiler/inference.jl +++ b/test/compiler/inference.jl @@ -3408,3 +3408,8 @@ end @test @inferred(f40177(T)) == fieldtype(T, 1) end end + +# issue #41908 +f41908(x::Complex{T}) where {String<:T<:String} = 1 +g41908() = f41908(Any[1][1]) +@test only(Base.return_types(g41908, ())) <: Int From e2377f18072da0ff83ba08ba0d6558dd7a4afb74 Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Wed, 25 Aug 2021 01:36:27 -0500 Subject: [PATCH 116/135] Various inferrability improvements (#41917) - two functions affected by `Core.Box` (#15276) were ameliorated - type info added to the `stack` field of `ExceptionStack` - avoid unknown dispatch from de-specialized code Co-authored-by: Jameson Nash --- base/arrayshow.jl | 33 ++++++++++--------- base/error.jl | 2 +- base/range.jl | 13 ++++---- contrib/generate_precompile.jl | 2 +- stdlib/Logging/src/ConsoleLogger.jl | 2 +- stdlib/REPL/src/docview.jl | 10 ++++-- stdlib/Test/src/Test.jl | 50 +++++++++++++++-------------- 7 files changed, 61 insertions(+), 51 deletions(-) diff --git a/base/arrayshow.jl b/base/arrayshow.jl index 1e9f3e59729e6b..0d480b64bb32d4 100644 --- a/base/arrayshow.jl +++ b/base/arrayshow.jl @@ -59,7 +59,8 @@ column going across the screen. """ function alignment(io::IO, @nospecialize(X::AbstractVecOrMat), rows::AbstractVector{T}, cols::AbstractVector{V}, - cols_if_complete::Integer, cols_otherwise::Integer, sep::Integer) where {T,V} + cols_if_complete::Integer, cols_otherwise::Integer, sep::Integer, + #= `size(X) may not infer, set this in caller =# ncols::Integer=size(X, 2)) where {T,V} a = Tuple{T, V}[] for j in cols # need to go down each column one at a time l = r = 0 @@ -78,7 +79,7 @@ function alignment(io::IO, @nospecialize(X::AbstractVecOrMat), break end end - if 1 < length(a) < length(axes(X,2)) + if 1 < length(a) < ncols while sum(map(sum,a)) + sep*length(a) >= cols_otherwise pop!(a) end @@ -95,7 +96,8 @@ is specified as string sep. """ function print_matrix_row(io::IO, @nospecialize(X::AbstractVecOrMat), A::Vector, - i::Integer, cols::AbstractVector, sep::AbstractString) + i::Integer, cols::AbstractVector, sep::AbstractString, + #= `axes(X)` may not infer, set this in caller =# idxlast::Integer=last(axes(X, 2))) for (k, j) = enumerate(cols) k > length(A) && break if isassigned(X,Int(i),Int(j)) # isassigned accepts only `Int` indices @@ -114,7 +116,7 @@ function print_matrix_row(io::IO, sx = undef_ref_str end l = repeat(" ", A[k][1]-a[1]) # pad on left and right as needed - r = j == axes(X, 2)[end] ? "" : repeat(" ", A[k][2]-a[2]) + r = j == idxlast ? "" : repeat(" ", A[k][2]-a[2]) prettysx = replace_in_print_matrix(X,i,j,sx) print(io, l, prettysx, r) if k < length(A); print(io, sep); end @@ -171,6 +173,7 @@ end function _print_matrix(io, @nospecialize(X::AbstractVecOrMat), pre, sep, post, hdots, vdots, ddots, hmod, vmod, rowsA, colsA) hmod, vmod = Int(hmod)::Int, Int(vmod)::Int + ncols, idxlast = length(colsA), last(colsA) if !(get(io, :limit, false)::Bool) screenheight = screenwidth = typemax(Int) else @@ -201,26 +204,26 @@ function _print_matrix(io, @nospecialize(X::AbstractVecOrMat), pre, sep, post, h else colsA = [colsA;] end - A = alignment(io, X, rowsA, colsA, screenwidth, screenwidth, sepsize) + A = alignment(io, X, rowsA, colsA, screenwidth, screenwidth, sepsize, ncols) # Nine-slicing is accomplished using print_matrix_row repeatedly if m <= screenheight # rows fit vertically on screen if n <= length(A) # rows and cols fit so just print whole matrix in one piece for i in rowsA print(io, i == first(rowsA) ? pre : presp) - print_matrix_row(io, X,A,i,colsA,sep) + print_matrix_row(io, X,A,i,colsA,sep,idxlast) print(io, i == last(rowsA) ? post : postsp) if i != last(rowsA); println(io); end end else # rows fit down screen but cols don't, so need horizontal ellipsis c = div(screenwidth-length(hdots)::Int+1,2)+1 # what goes to right of ellipsis - Ralign = reverse(alignment(io, X, rowsA, reverse(colsA), c, c, sepsize)) # alignments for right + Ralign = reverse(alignment(io, X, rowsA, reverse(colsA), c, c, sepsize, ncols)) # alignments for right c = screenwidth - sum(map(sum,Ralign)) - (length(Ralign)-1)*sepsize - length(hdots)::Int - Lalign = alignment(io, X, rowsA, colsA, c, c, sepsize) # alignments for left of ellipsis + Lalign = alignment(io, X, rowsA, colsA, c, c, sepsize, ncols) # alignments for left of ellipsis for i in rowsA print(io, i == first(rowsA) ? pre : presp) - print_matrix_row(io, X,Lalign,i,colsA[1:length(Lalign)],sep) + print_matrix_row(io, X,Lalign,i,colsA[1:length(Lalign)],sep,idxlast) print(io, (i - first(rowsA)) % hmod == 0 ? hdots : repeat(" ", length(hdots)::Int)) - print_matrix_row(io, X, Ralign, i, (n - length(Ralign)) .+ colsA, sep) + print_matrix_row(io, X, Ralign, i, (n - length(Ralign)) .+ colsA, sep, idxlast) print(io, i == last(rowsA) ? post : postsp) if i != last(rowsA); println(io); end end @@ -229,7 +232,7 @@ function _print_matrix(io, @nospecialize(X::AbstractVecOrMat), pre, sep, post, h if n <= length(A) # rows don't fit, cols do, so only vertical ellipsis for i in rowsA print(io, i == first(rowsA) ? pre : presp) - print_matrix_row(io, X,A,i,colsA,sep) + print_matrix_row(io, X,A,i,colsA,sep,idxlast) print(io, i == last(rowsA) ? post : postsp) if i != rowsA[end] || i == rowsA[halfheight]; println(io); end if i == rowsA[halfheight] @@ -240,15 +243,15 @@ function _print_matrix(io, @nospecialize(X::AbstractVecOrMat), pre, sep, post, h end else # neither rows nor cols fit, so use all 3 kinds of dots c = div(screenwidth-length(hdots)::Int+1,2)+1 - Ralign = reverse(alignment(io, X, rowsA, reverse(colsA), c, c, sepsize)) + Ralign = reverse(alignment(io, X, rowsA, reverse(colsA), c, c, sepsize, ncols)) c = screenwidth - sum(map(sum,Ralign)) - (length(Ralign)-1)*sepsize - length(hdots)::Int - Lalign = alignment(io, X, rowsA, colsA, c, c, sepsize) + Lalign = alignment(io, X, rowsA, colsA, c, c, sepsize, ncols) r = mod((length(Ralign)-n+1),vmod) # where to put dots on right half for i in rowsA print(io, i == first(rowsA) ? pre : presp) - print_matrix_row(io, X,Lalign,i,colsA[1:length(Lalign)],sep) + print_matrix_row(io, X,Lalign,i,colsA[1:length(Lalign)],sep,idxlast) print(io, (i - first(rowsA)) % hmod == 0 ? hdots : repeat(" ", length(hdots)::Int)) - print_matrix_row(io, X,Ralign,i,(n-length(Ralign)).+colsA,sep) + print_matrix_row(io, X,Ralign,i,(n-length(Ralign)).+colsA,sep,idxlast) print(io, i == last(rowsA) ? post : postsp) if i != rowsA[end] || i == rowsA[halfheight]; println(io); end if i == rowsA[halfheight] diff --git a/base/error.jl b/base/error.jl index 0976b9c28fa8cb..9a6c6a5581b6fb 100644 --- a/base/error.jl +++ b/base/error.jl @@ -124,7 +124,7 @@ function catch_backtrace() end struct ExceptionStack <: AbstractArray{Any,1} - stack + stack::Array{Any,1} end """ diff --git a/base/range.jl b/base/range.jl index 1ab21c3d07d10a..f4bf71c4f70c35 100644 --- a/base/range.jl +++ b/base/range.jl @@ -615,22 +615,23 @@ function print_range(io::IO, r::AbstractRange, maxpossiblecols = div(screenwidth, 1+sepsize) # assume each element is at least 1 char + 1 separator colsr = n <= maxpossiblecols ? (1:n) : [1:div(maxpossiblecols,2)+1; (n-div(maxpossiblecols,2)):n] rowmatrix = reshape(r[colsr], 1, length(colsr)) # treat the range as a one-row matrix for print_matrix_row - A = alignment(io, rowmatrix, 1:m, 1:length(rowmatrix), screenwidth, screenwidth, sepsize) # how much space range takes + nrow, idxlast = size(rowmatrix, 2), last(axes(rowmatrix, 2)) + A = alignment(io, rowmatrix, 1:m, 1:length(rowmatrix), screenwidth, screenwidth, sepsize, nrow) # how much space range takes if n <= length(A) # cols fit screen, so print out all elements print(io, pre) # put in pre chars - print_matrix_row(io,rowmatrix,A,1,1:n,sep) # the entire range + print_matrix_row(io,rowmatrix,A,1,1:n,sep,idxlast) # the entire range print(io, post) # add the post characters else # cols don't fit so put horiz ellipsis in the middle # how many chars left after dividing width of screen in half # and accounting for the horiz ellipsis c = div(screenwidth-length(hdots)+1,2)+1 # chars remaining for each side of rowmatrix - alignR = reverse(alignment(io, rowmatrix, 1:m, length(rowmatrix):-1:1, c, c, sepsize)) # which cols of rowmatrix to put on the right + alignR = reverse(alignment(io, rowmatrix, 1:m, length(rowmatrix):-1:1, c, c, sepsize, nrow)) # which cols of rowmatrix to put on the right c = screenwidth - sum(map(sum,alignR)) - (length(alignR)-1)*sepsize - length(hdots) - alignL = alignment(io, rowmatrix, 1:m, 1:length(rowmatrix), c, c, sepsize) # which cols of rowmatrix to put on the left + alignL = alignment(io, rowmatrix, 1:m, 1:length(rowmatrix), c, c, sepsize, nrow) # which cols of rowmatrix to put on the left print(io, pre) # put in pre chars - print_matrix_row(io, rowmatrix,alignL,1,1:length(alignL),sep) # left part of range + print_matrix_row(io, rowmatrix,alignL,1,1:length(alignL),sep,idxlast) # left part of range print(io, hdots) # horizontal ellipsis - print_matrix_row(io, rowmatrix,alignR,1,length(rowmatrix)-length(alignR)+1:length(rowmatrix),sep) # right part of range + print_matrix_row(io, rowmatrix,alignR,1,length(rowmatrix)-length(alignR)+1:length(rowmatrix),sep,idxlast) # right part of range print(io, post) # post chars end end diff --git a/contrib/generate_precompile.jl b/contrib/generate_precompile.jl index bb760f70ab8678..a9bf83a9f9674e 100644 --- a/contrib/generate_precompile.jl +++ b/contrib/generate_precompile.jl @@ -377,7 +377,7 @@ function generate_precompile_statements() # XXX: precompile doesn't currently handle overloaded Vararg arguments very well. # Replacing N with a large number works around it. l = l.args[end] - if isexpr(l, :curly) && length(l.args) == 2 && l.args[1] == :Vararg # Vararg{T} + if isexpr(l, :curly) && length(l.args) == 2 && l.args[1] === :Vararg # Vararg{T} push!(l.args, 100) # form Vararg{T, 100} instead end end diff --git a/stdlib/Logging/src/ConsoleLogger.jl b/stdlib/Logging/src/ConsoleLogger.jl index f13a8aa2f633b4..4e32b6b71f6562 100644 --- a/stdlib/Logging/src/ConsoleLogger.jl +++ b/stdlib/Logging/src/ConsoleLogger.jl @@ -70,7 +70,7 @@ function default_metafmt(level::LogLevel, _module, group, id, file, line) prefix = string(level == Warn ? "Warning" : string(level), ':') suffix::String = "" Info <= level < Warn && return color, prefix, suffix - _module !== nothing && (suffix *= "$(_module)") + _module !== nothing && (suffix *= string(_module)::String) if file !== nothing _module !== nothing && (suffix *= " ") suffix *= Base.contractuser(file)::String diff --git a/stdlib/REPL/src/docview.jl b/stdlib/REPL/src/docview.jl index f4467b3e787bc0..c4b43399a89c0e 100644 --- a/stdlib/REPL/src/docview.jl +++ b/stdlib/REPL/src/docview.jl @@ -402,8 +402,12 @@ function symbol_latex(s::String) return get(symbols_latex, s, "") end -function repl_latex(io::IO, s::String) - latex = symbol_latex(s) +function repl_latex(io::IO, s0::String) + # This has rampant `Core.Box` problems (#15276). Use the tricks of + # https://docs.julialang.org/en/v1/manual/performance-tips/#man-performance-captured + # We're changing some of the values so the `let` trick isn't applicable. + s::String = s0 + latex::String = symbol_latex(s) if isempty(latex) # Decompose NFC-normalized identifier to match tab-completion # input if the first search came up empty. @@ -420,7 +424,7 @@ function repl_latex(io::IO, s::String) print(io, "\"") printstyled(io, s, color=:cyan) print(io, "\" can be typed by ") - state = '\0' + state::Char = '\0' with_output_color(:cyan, io) do io for c in s cstr = string(c) diff --git a/stdlib/Test/src/Test.jl b/stdlib/Test/src/Test.jl index 0c9cfd5ccafd12..c616c7c59a9ba5 100644 --- a/stdlib/Test/src/Test.jl +++ b/stdlib/Test/src/Test.jl @@ -1580,30 +1580,32 @@ function _inferred(ex, mod, allow = :(Union{})) ex = Expr(:call, GlobalRef(Test, :_materialize_broadcasted), farg, ex.args[2:end]...) end - Base.remove_linenums!(quote - let - allow = $(esc(allow)) - allow isa Type || throw(ArgumentError("@inferred requires a type as second argument")) - $(if any(a->(Meta.isexpr(a, :kw) || Meta.isexpr(a, :parameters)), ex.args) - # Has keywords - args = gensym() - kwargs = gensym() - quote - $(esc(args)), $(esc(kwargs)), result = $(esc(Expr(:call, _args_and_call, ex.args[2:end]..., ex.args[1]))) - inftypes = $(gen_call_with_extracted_types(mod, Base.return_types, :($(ex.args[1])($(args)...; $(kwargs)...)))) - end - else - # No keywords - quote - args = ($([esc(ex.args[i]) for i = 2:length(ex.args)]...),) - result = $(esc(ex.args[1]))(args...) - inftypes = Base.return_types($(esc(ex.args[1])), Base.typesof(args...)) - end - end) - @assert length(inftypes) == 1 - rettype = result isa Type ? Type{result} : typeof(result) - rettype <: allow || rettype == typesplit(inftypes[1], allow) || error("return type $rettype does not match inferred return type $(inftypes[1])") - result + Base.remove_linenums!(let ex = ex; + quote + let + allow = $(esc(allow)) + allow isa Type || throw(ArgumentError("@inferred requires a type as second argument")) + $(if any(a->(Meta.isexpr(a, :kw) || Meta.isexpr(a, :parameters)), ex.args) + # Has keywords + args = gensym() + kwargs = gensym() + quote + $(esc(args)), $(esc(kwargs)), result = $(esc(Expr(:call, _args_and_call, ex.args[2:end]..., ex.args[1]))) + inftypes = $(gen_call_with_extracted_types(mod, Base.return_types, :($(ex.args[1])($(args)...; $(kwargs)...)))) + end + else + # No keywords + quote + args = ($([esc(ex.args[i]) for i = 2:length(ex.args)]...),) + result = $(esc(ex.args[1]))(args...) + inftypes = Base.return_types($(esc(ex.args[1])), Base.typesof(args...)) + end + end) + @assert length(inftypes) == 1 + rettype = result isa Type ? Type{result} : typeof(result) + rettype <: allow || rettype == typesplit(inftypes[1], allow) || error("return type $rettype does not match inferred return type $(inftypes[1])") + result + end end end) end From bb2d8630f3aeb99c38c659a35ee9aa57bb71012a Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Wed, 25 Aug 2021 17:32:15 +0900 Subject: [PATCH 117/135] deprecate `@_(no)inline_meta` in favor of no-arg `@(no)inline` (#41323) v1.8 will publicly support these annotations within a function body and so we can replace all the usages of `@_inline_meta` and `@_noinline_meta` with each no-arg version. We may want to deprecate them rather than remove entirely them though, since I found a quite few packages rely on these "internal" macros... - - --- base/Base.jl | 42 +++++----- base/abstractarray.jl | 114 +++++++++++++-------------- base/array.jl | 32 ++++---- base/boot.jl | 31 +++----- base/checked.jl | 12 +-- base/compiler/compiler.jl | 18 ++--- base/deprecated.jl | 7 ++ base/error.jl | 6 +- base/essentials.jl | 4 +- base/experimental.jl | 4 +- base/expr.jl | 2 - base/gcutils.jl | 6 +- base/generator.jl | 2 +- base/indices.jl | 32 ++++---- base/loading.jl | 2 +- base/multidimensional.jl | 6 +- base/ntuple.jl | 10 +-- base/number.jl | 4 +- base/operators.jl | 10 +-- base/pointer.jl | 2 +- base/promotion.jl | 22 +++--- base/range.jl | 40 +++++----- base/rational.jl | 2 +- base/reinterpretarray.jl | 12 +-- base/reshapedarray.jl | 2 +- base/set.jl | 2 +- base/subarray.jl | 84 ++++++++++---------- base/tuple.jl | 42 +++++----- base/twiceprecision.jl | 4 +- stdlib/LinearAlgebra/src/adjtrans.jl | 2 +- test/compiler/codegen.jl | 2 +- test/opaque_closure.jl | 2 +- test/syntax.jl | 2 +- test/vecelement.jl | 2 +- 34 files changed, 279 insertions(+), 287 deletions(-) diff --git a/base/Base.jl b/base/Base.jl index 09fdcb1689de37..e4c65b3493cbaf 100644 --- a/base/Base.jl +++ b/base/Base.jl @@ -20,46 +20,42 @@ include(path::String) = include(Base, path) const is_primary_base_module = ccall(:jl_module_parent, Ref{Module}, (Any,), Base) === Core.Main ccall(:jl_set_istopmod, Cvoid, (Any, Bool), Base, is_primary_base_module) -# The real @inline macro is not available until after array.jl, so this -# internal macro splices the meta Expr directly into the function body. -macro _inline_meta() - Expr(:meta, :inline) -end -macro _noinline_meta() - Expr(:meta, :noinline) -end +# The @inline/@noinline macros that can be applied to a function declaration are not available +# until after array.jl, and so we will mark them within a function body instead. +macro inline() Expr(:meta, :inline) end +macro noinline() Expr(:meta, :noinline) end # Try to help prevent users from shooting them-selves in the foot # with ambiguities by defining a few common and critical operations # (and these don't need the extra convert code) -getproperty(x::Module, f::Symbol) = (@_inline_meta; getfield(x, f)) +getproperty(x::Module, f::Symbol) = (@inline; getfield(x, f)) setproperty!(x::Module, f::Symbol, v) = setfield!(x, f, v) # to get a decent error -getproperty(x::Type, f::Symbol) = (@_inline_meta; getfield(x, f)) +getproperty(x::Type, f::Symbol) = (@inline; getfield(x, f)) setproperty!(x::Type, f::Symbol, v) = error("setfield! fields of Types should not be changed") -getproperty(x::Tuple, f::Int) = (@_inline_meta; getfield(x, f)) +getproperty(x::Tuple, f::Int) = (@inline; getfield(x, f)) setproperty!(x::Tuple, f::Int, v) = setfield!(x, f, v) # to get a decent error -getproperty(x, f::Symbol) = (@_inline_meta; getfield(x, f)) +getproperty(x, f::Symbol) = (@inline; getfield(x, f)) setproperty!(x, f::Symbol, v) = setfield!(x, f, convert(fieldtype(typeof(x), f), v)) dotgetproperty(x, f) = getproperty(x, f) -getproperty(x::Module, f::Symbol, order::Symbol) = (@_inline_meta; getfield(x, f, order)) +getproperty(x::Module, f::Symbol, order::Symbol) = (@inline; getfield(x, f, order)) setproperty!(x::Module, f::Symbol, v, order::Symbol) = setfield!(x, f, v, order) # to get a decent error -getproperty(x::Type, f::Symbol, order::Symbol) = (@_inline_meta; getfield(x, f, order)) +getproperty(x::Type, f::Symbol, order::Symbol) = (@inline; getfield(x, f, order)) setproperty!(x::Type, f::Symbol, v, order::Symbol) = error("setfield! fields of Types should not be changed") -getproperty(x::Tuple, f::Int, order::Symbol) = (@_inline_meta; getfield(x, f, order)) +getproperty(x::Tuple, f::Int, order::Symbol) = (@inline; getfield(x, f, order)) setproperty!(x::Tuple, f::Int, v, order::Symbol) = setfield!(x, f, v, order) # to get a decent error -getproperty(x, f::Symbol, order::Symbol) = (@_inline_meta; getfield(x, f, order)) -setproperty!(x, f::Symbol, v, order::Symbol) = (@_inline_meta; setfield!(x, f, convert(fieldtype(typeof(x), f), v), order)) +getproperty(x, f::Symbol, order::Symbol) = (@inline; getfield(x, f, order)) +setproperty!(x, f::Symbol, v, order::Symbol) = (@inline; setfield!(x, f, convert(fieldtype(typeof(x), f), v), order)) swapproperty!(x, f::Symbol, v, order::Symbol=:notatomic) = - (@_inline_meta; Core.swapfield!(x, f, convert(fieldtype(typeof(x), f), v), order)) + (@inline; Core.swapfield!(x, f, convert(fieldtype(typeof(x), f), v), order)) modifyproperty!(x, f::Symbol, op, v, order::Symbol=:notatomic) = - (@_inline_meta; Core.modifyfield!(x, f, op, v, order)) + (@inline; Core.modifyfield!(x, f, op, v, order)) replaceproperty!(x, f::Symbol, expected, desired, success_order::Symbol=:notatomic, fail_order::Symbol=success_order) = - (@_inline_meta; Core.replacefield!(x, f, expected, convert(fieldtype(typeof(x), f), desired), success_order, fail_order)) + (@inline; Core.replacefield!(x, f, expected, convert(fieldtype(typeof(x), f), desired), success_order, fail_order)) include("coreio.jl") @@ -107,9 +103,9 @@ include("options.jl") include("promotion.jl") include("tuple.jl") include("expr.jl") -Pair{A, B}(@nospecialize(a), @nospecialize(b)) where {A, B} = (@_inline_meta; Pair{A, B}(convert(A, a)::A, convert(B, b)::B)) -#Pair{Any, B}(@nospecialize(a::Any), b) where {B} = (@_inline_meta; Pair{Any, B}(a, Base.convert(B, b)::B)) -#Pair{A, Any}(a, @nospecialize(b::Any)) where {A} = (@_inline_meta; Pair{A, Any}(Base.convert(A, a)::A, b)) +Pair{A, B}(@nospecialize(a), @nospecialize(b)) where {A, B} = (@inline; Pair{A, B}(convert(A, a)::A, convert(B, b)::B)) +#Pair{Any, B}(@nospecialize(a::Any), b) where {B} = (@inline; Pair{Any, B}(a, Base.convert(B, b)::B)) +#Pair{A, Any}(a, @nospecialize(b::Any)) where {A} = (@inline; Pair{A, Any}(Base.convert(A, a)::A, b)) include("pair.jl") include("traits.jl") include("range.jl") diff --git a/base/abstractarray.jl b/base/abstractarray.jl index 0a88e733adbc0f..5ded231fa2be27 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -70,7 +70,7 @@ ix[(begin+1):end] # works for generalized indexes ``` """ function axes(A::AbstractArray{T,N}, d) where {T,N} - @_inline_meta + @inline d::Integer <= N ? axes(A)[d] : OneTo(1) end @@ -91,7 +91,7 @@ julia> axes(A) ``` """ function axes(A) - @_inline_meta + @inline map(oneto, size(A)) end @@ -113,7 +113,7 @@ require_one_based_indexing(A...) = !has_offset_axes(A...) || throw(ArgumentError # for d=1. 1d arrays are heavily used, and the first dimension comes up # in other applications. axes1(A::AbstractArray{<:Any,0}) = OneTo(1) -axes1(A::AbstractArray) = (@_inline_meta; axes(A)[1]) +axes1(A::AbstractArray) = (@inline; axes(A)[1]) axes1(iter) = oneto(length(iter)) """ @@ -270,13 +270,13 @@ julia> length([1 2; 3 4]) 4 ``` """ -length(t::AbstractArray) = (@_inline_meta; prod(size(t))) +length(t::AbstractArray) = (@inline; prod(size(t))) # `eachindex` is mostly an optimization of `keys` eachindex(itrs...) = keys(itrs...) # eachindex iterates over all indices. IndexCartesian definitions are later. -eachindex(A::AbstractVector) = (@_inline_meta(); axes1(A)) +eachindex(A::AbstractVector) = (@inline(); axes1(A)) @noinline function throw_eachindex_mismatch_indices(::IndexLinear, inds...) @@ -321,27 +321,27 @@ CartesianIndex(1, 1) CartesianIndex(2, 1) ``` """ -eachindex(A::AbstractArray) = (@_inline_meta(); eachindex(IndexStyle(A), A)) +eachindex(A::AbstractArray) = (@inline(); eachindex(IndexStyle(A), A)) function eachindex(A::AbstractArray, B::AbstractArray) - @_inline_meta + @inline eachindex(IndexStyle(A,B), A, B) end function eachindex(A::AbstractArray, B::AbstractArray...) - @_inline_meta + @inline eachindex(IndexStyle(A,B...), A, B...) end -eachindex(::IndexLinear, A::AbstractArray) = (@_inline_meta; oneto(length(A))) -eachindex(::IndexLinear, A::AbstractVector) = (@_inline_meta; axes1(A)) +eachindex(::IndexLinear, A::AbstractArray) = (@inline; oneto(length(A))) +eachindex(::IndexLinear, A::AbstractVector) = (@inline; axes1(A)) function eachindex(::IndexLinear, A::AbstractArray, B::AbstractArray...) - @_inline_meta + @inline indsA = eachindex(IndexLinear(), A) _all_match_first(X->eachindex(IndexLinear(), X), indsA, B...) || throw_eachindex_mismatch_indices(IndexLinear(), eachindex(A), eachindex.(B)...) indsA end function _all_match_first(f::F, inds, A, B...) where F<:Function - @_inline_meta + @inline (inds == f(A)) & _all_match_first(f, inds, B...) end _all_match_first(f::F, inds) where F<:Function = true @@ -369,8 +369,8 @@ julia> lastindex(rand(3,4,5), 2) 4 ``` """ -lastindex(a::AbstractArray) = (@_inline_meta; last(eachindex(IndexLinear(), a))) -lastindex(a, d) = (@_inline_meta; last(axes(a, d))) +lastindex(a::AbstractArray) = (@inline; last(eachindex(IndexLinear(), a))) +lastindex(a, d) = (@inline; last(axes(a, d))) """ firstindex(collection) -> Integer @@ -392,8 +392,8 @@ julia> firstindex(rand(3,4,5), 2) 1 ``` """ -firstindex(a::AbstractArray) = (@_inline_meta; first(eachindex(IndexLinear(), a))) -firstindex(a, d) = (@_inline_meta; first(axes(a, d))) +firstindex(a::AbstractArray) = (@inline; first(eachindex(IndexLinear(), a))) +firstindex(a, d) = (@inline; first(axes(a, d))) first(a::AbstractArray) = a[first(eachindex(a))] @@ -583,7 +583,7 @@ function trailingsize(inds::Indices, n) end # This version is type-stable even if inds is heterogeneous function trailingsize(inds::Indices) - @_inline_meta + @inline prod(map(length, inds)) end @@ -631,18 +631,18 @@ false ``` """ function checkbounds(::Type{Bool}, A::AbstractArray, I...) - @_inline_meta + @inline checkbounds_indices(Bool, axes(A), I) end # Linear indexing is explicitly allowed when there is only one (non-cartesian) index function checkbounds(::Type{Bool}, A::AbstractArray, i) - @_inline_meta + @inline checkindex(Bool, eachindex(IndexLinear(), A), i) end # As a special extension, allow using logical arrays that match the source array exactly function checkbounds(::Type{Bool}, A::AbstractArray{<:Any,N}, I::AbstractArray{Bool,N}) where N - @_inline_meta + @inline axes(A) == axes(I) end @@ -652,7 +652,7 @@ end Throw an error if the specified indices `I` are not in bounds for the given array `A`. """ function checkbounds(A::AbstractArray, I...) - @_inline_meta + @inline checkbounds(Bool, A, I...) || throw_boundserror(A, I) nothing end @@ -678,17 +678,17 @@ of `IA`. See also [`checkbounds`](@ref). """ function checkbounds_indices(::Type{Bool}, IA::Tuple, I::Tuple) - @_inline_meta + @inline checkindex(Bool, IA[1], I[1])::Bool & checkbounds_indices(Bool, tail(IA), tail(I)) end function checkbounds_indices(::Type{Bool}, ::Tuple{}, I::Tuple) - @_inline_meta + @inline checkindex(Bool, OneTo(1), I[1])::Bool & checkbounds_indices(Bool, (), tail(I)) end -checkbounds_indices(::Type{Bool}, IA::Tuple, ::Tuple{}) = (@_inline_meta; all(x->length(x)==1, IA)) +checkbounds_indices(::Type{Bool}, IA::Tuple, ::Tuple{}) = (@inline; all(x->length(x)==1, IA)) checkbounds_indices(::Type{Bool}, ::Tuple{}, ::Tuple{}) = true -throw_boundserror(A, I) = (@_noinline_meta; throw(BoundsError(A, I))) +throw_boundserror(A, I) = (@noinline; throw(BoundsError(A, I))) # check along a single dimension """ @@ -722,7 +722,7 @@ end checkindex(::Type{Bool}, indx::AbstractUnitRange, I::AbstractVector{Bool}) = indx == axes1(I) checkindex(::Type{Bool}, indx::AbstractUnitRange, I::AbstractArray{Bool}) = false function checkindex(::Type{Bool}, inds::AbstractUnitRange, I::AbstractArray) - @_inline_meta + @inline b = true for i in I b &= checkindex(Bool, inds, i) @@ -1163,7 +1163,7 @@ end # convenience in cases that work. pointer(x::AbstractArray{T}) where {T} = unsafe_convert(Ptr{T}, x) function pointer(x::AbstractArray{T}, i::Integer) where T - @_inline_meta + @inline unsafe_convert(Ptr{T}, x) + Int(_memory_offset(x, i))::Int end @@ -1221,7 +1221,7 @@ end @propagate_inbounds getindex(A::Array, i1::Integer, I::Integer...) = A[to_indices(A, (i1, I...))...] function unsafe_getindex(A::AbstractArray, I...) - @_inline_meta + @inline @inbounds r = getindex(A, I...) r end @@ -1240,7 +1240,7 @@ _getindex(::IndexStyle, A::AbstractArray, I...) = _getindex(::IndexLinear, A::AbstractVector, i::Int) = (@_propagate_inbounds_meta; getindex(A, i)) # ambiguity resolution in case packages specialize this (to be avoided if at all possible, but see Interpolations.jl) _getindex(::IndexLinear, A::AbstractArray, i::Int) = (@_propagate_inbounds_meta; getindex(A, i)) function _getindex(::IndexLinear, A::AbstractArray, I::Vararg{Int,M}) where M - @_inline_meta + @inline @boundscheck checkbounds(A, I...) # generally _to_linear_index requires bounds checking @inbounds r = getindex(A, _to_linear_index(A, I...)) r @@ -1248,11 +1248,11 @@ end _to_linear_index(A::AbstractArray, i::Integer) = i _to_linear_index(A::AbstractVector, i::Integer, I::Integer...) = i _to_linear_index(A::AbstractArray) = first(LinearIndices(A)) -_to_linear_index(A::AbstractArray, I::Integer...) = (@_inline_meta; _sub2ind(A, I...)) +_to_linear_index(A::AbstractArray, I::Integer...) = (@inline; _sub2ind(A, I...)) ## IndexCartesian Scalar indexing: Canonical method is full dimensionality of Ints function _getindex(::IndexCartesian, A::AbstractArray, I::Vararg{Int,M}) where M - @_inline_meta + @inline @boundscheck checkbounds(A, I...) # generally _to_subscript_indices requires bounds checking @inbounds r = getindex(A, _to_subscript_indices(A, I...)...) r @@ -1261,13 +1261,13 @@ function _getindex(::IndexCartesian, A::AbstractArray{T,N}, I::Vararg{Int, N}) w @_propagate_inbounds_meta getindex(A, I...) end -_to_subscript_indices(A::AbstractArray, i::Integer) = (@_inline_meta; _unsafe_ind2sub(A, i)) -_to_subscript_indices(A::AbstractArray{T,N}) where {T,N} = (@_inline_meta; fill_to_length((), 1, Val(N))) +_to_subscript_indices(A::AbstractArray, i::Integer) = (@inline; _unsafe_ind2sub(A, i)) +_to_subscript_indices(A::AbstractArray{T,N}) where {T,N} = (@inline; fill_to_length((), 1, Val(N))) _to_subscript_indices(A::AbstractArray{T,0}) where {T} = () _to_subscript_indices(A::AbstractArray{T,0}, i::Integer) where {T} = () _to_subscript_indices(A::AbstractArray{T,0}, I::Integer...) where {T} = () function _to_subscript_indices(A::AbstractArray{T,N}, I::Integer...) where {T,N} - @_inline_meta + @inline J, Jrem = IteratorsMD.split(I, Val(N)) _to_subscript_indices(A, J, Jrem) end @@ -1275,15 +1275,15 @@ _to_subscript_indices(A::AbstractArray, J::Tuple, Jrem::Tuple{}) = __to_subscript_indices(A, axes(A), J, Jrem) function __to_subscript_indices(A::AbstractArray, ::Tuple{AbstractUnitRange,Vararg{AbstractUnitRange}}, J::Tuple, Jrem::Tuple{}) - @_inline_meta + @inline (J..., map(first, tail(_remaining_size(J, axes(A))))...) end _to_subscript_indices(A, J::Tuple, Jrem::Tuple) = J # already bounds-checked, safe to drop _to_subscript_indices(A::AbstractArray{T,N}, I::Vararg{Int,N}) where {T,N} = I _remaining_size(::Tuple{Any}, t::Tuple) = t -_remaining_size(h::Tuple, t::Tuple) = (@_inline_meta; _remaining_size(tail(h), tail(t))) +_remaining_size(h::Tuple, t::Tuple) = (@inline; _remaining_size(tail(h), tail(t))) _unsafe_ind2sub(::Tuple{}, i) = () # _ind2sub may throw(BoundsError()) in this case -_unsafe_ind2sub(sz, i) = (@_inline_meta; _ind2sub(sz, i)) +_unsafe_ind2sub(sz, i) = (@inline; _ind2sub(sz, i)) ## Setindex! is defined similarly. We first dispatch to an internal _setindex! # function that allows dispatch on array storage @@ -1315,7 +1315,7 @@ function setindex!(A::AbstractArray, v, I...) _setindex!(IndexStyle(A), A, v, to_indices(A, I)...) end function unsafe_setindex!(A::AbstractArray, v, I...) - @_inline_meta + @inline @inbounds r = setindex!(A, v, I...) r end @@ -1333,7 +1333,7 @@ _setindex!(::IndexStyle, A::AbstractArray, v, I...) = ## IndexLinear Scalar indexing _setindex!(::IndexLinear, A::AbstractArray, v, i::Int) = (@_propagate_inbounds_meta; setindex!(A, v, i)) function _setindex!(::IndexLinear, A::AbstractArray, v, I::Vararg{Int,M}) where M - @_inline_meta + @inline @boundscheck checkbounds(A, I...) @inbounds r = setindex!(A, v, _to_linear_index(A, I...)) r @@ -1345,7 +1345,7 @@ function _setindex!(::IndexCartesian, A::AbstractArray{T,N}, v, I::Vararg{Int, N setindex!(A, v, I...) end function _setindex!(::IndexCartesian, A::AbstractArray, v, I::Vararg{Int,M}) where M - @_inline_meta + @inline @boundscheck checkbounds(A, I...) @inbounds r = setindex!(A, v, _to_subscript_indices(A, I...)...) r @@ -1412,7 +1412,7 @@ much more common case where aliasing does not occur. By default, `Base.unaliascopy(A)`. """ unaliascopy(A::Array) = copy(A) -unaliascopy(A::AbstractArray)::typeof(A) = (@_noinline_meta; _unaliascopy(A, copy(A))) +unaliascopy(A::AbstractArray)::typeof(A) = (@noinline; _unaliascopy(A, copy(A))) _unaliascopy(A::T, C::T) where {T} = C _unaliascopy(A, C) = throw(ArgumentError(""" an array of type `$(typename(typeof(A)).wrapper)` shares memory with another argument @@ -2550,12 +2550,12 @@ end # _sub2ind and _ind2sub # fallbacks function _sub2ind(A::AbstractArray, I...) - @_inline_meta + @inline _sub2ind(axes(A), I...) end function _ind2sub(A::AbstractArray, ind) - @_inline_meta + @inline _ind2sub(axes(A), ind) end @@ -2563,25 +2563,25 @@ end _sub2ind(::Tuple{}) = 1 _sub2ind(::DimsInteger) = 1 _sub2ind(::Indices) = 1 -_sub2ind(::Tuple{}, I::Integer...) = (@_inline_meta; _sub2ind_recurse((), 1, 1, I...)) +_sub2ind(::Tuple{}, I::Integer...) = (@inline; _sub2ind_recurse((), 1, 1, I...)) # Generic cases -_sub2ind(dims::DimsInteger, I::Integer...) = (@_inline_meta; _sub2ind_recurse(dims, 1, 1, I...)) -_sub2ind(inds::Indices, I::Integer...) = (@_inline_meta; _sub2ind_recurse(inds, 1, 1, I...)) +_sub2ind(dims::DimsInteger, I::Integer...) = (@inline; _sub2ind_recurse(dims, 1, 1, I...)) +_sub2ind(inds::Indices, I::Integer...) = (@inline; _sub2ind_recurse(inds, 1, 1, I...)) # In 1d, there's a question of whether we're doing cartesian indexing # or linear indexing. Support only the former. _sub2ind(inds::Indices{1}, I::Integer...) = throw(ArgumentError("Linear indexing is not defined for one-dimensional arrays")) -_sub2ind(inds::Tuple{OneTo}, I::Integer...) = (@_inline_meta; _sub2ind_recurse(inds, 1, 1, I...)) # only OneTo is safe +_sub2ind(inds::Tuple{OneTo}, I::Integer...) = (@inline; _sub2ind_recurse(inds, 1, 1, I...)) # only OneTo is safe _sub2ind(inds::Tuple{OneTo}, i::Integer) = i _sub2ind_recurse(::Any, L, ind) = ind function _sub2ind_recurse(::Tuple{}, L, ind, i::Integer, I::Integer...) - @_inline_meta + @inline _sub2ind_recurse((), L, ind+(i-1)*L, I...) end function _sub2ind_recurse(inds, L, ind, i::Integer, I::Integer...) - @_inline_meta + @inline r1 = inds[1] _sub2ind_recurse(tail(inds), nextL(L, r1), ind+offsetin(i, r1)*L, I...) end @@ -2592,20 +2592,20 @@ nextL(L, r::Slice) = L*length(r.indices) offsetin(i, l::Integer) = i-1 offsetin(i, r::AbstractUnitRange) = i-first(r) -_ind2sub(::Tuple{}, ind::Integer) = (@_inline_meta; ind == 1 ? () : throw(BoundsError())) -_ind2sub(dims::DimsInteger, ind::Integer) = (@_inline_meta; _ind2sub_recurse(dims, ind-1)) -_ind2sub(inds::Indices, ind::Integer) = (@_inline_meta; _ind2sub_recurse(inds, ind-1)) +_ind2sub(::Tuple{}, ind::Integer) = (@inline; ind == 1 ? () : throw(BoundsError())) +_ind2sub(dims::DimsInteger, ind::Integer) = (@inline; _ind2sub_recurse(dims, ind-1)) +_ind2sub(inds::Indices, ind::Integer) = (@inline; _ind2sub_recurse(inds, ind-1)) _ind2sub(inds::Indices{1}, ind::Integer) = throw(ArgumentError("Linear indexing is not defined for one-dimensional arrays")) _ind2sub(inds::Tuple{OneTo}, ind::Integer) = (ind,) _ind2sub_recurse(::Tuple{}, ind) = (ind+1,) function _ind2sub_recurse(indslast::NTuple{1}, ind) - @_inline_meta + @inline (_lookup(ind, indslast[1]),) end function _ind2sub_recurse(inds, ind) - @_inline_meta + @inline r1 = inds[1] indnext, f, l = _div(ind, r1) (ind-l*indnext+f, _ind2sub_recurse(tail(inds), indnext)...) @@ -2636,7 +2636,7 @@ function _sub2ind_vecs(inds, I::AbstractVector...) end function _sub2ind!(Iout, inds, Iinds, I) - @_noinline_meta + @noinline for i in Iinds # Iout[i] = _sub2ind(inds, map(Ij -> Ij[i], I)...) Iout[i] = sub2ind_vec(inds, i, I) @@ -2644,8 +2644,8 @@ function _sub2ind!(Iout, inds, Iinds, I) Iout end -sub2ind_vec(inds, i, I) = (@_inline_meta; _sub2ind(inds, _sub2ind_vec(i, I...)...)) -_sub2ind_vec(i, I1, I...) = (@_inline_meta; (I1[i], _sub2ind_vec(i, I...)...)) +sub2ind_vec(inds, i, I) = (@inline; _sub2ind(inds, _sub2ind_vec(i, I...)...)) +_sub2ind_vec(i, I1, I...) = (@inline; (I1[i], _sub2ind_vec(i, I...)...)) _sub2ind_vec(i) = () function _ind2sub(inds::Union{DimsInteger{N},Indices{N}}, ind::AbstractVector{<:Integer}) where N diff --git a/base/array.jl b/base/array.jl index af75094460e4c4..6a16db66a8cfde 100644 --- a/base/array.jl +++ b/base/array.jl @@ -150,7 +150,7 @@ end size(a::Array, d::Integer) = arraysize(a, convert(Int, d)) size(a::Vector) = (arraysize(a,1),) size(a::Matrix) = (arraysize(a,1), arraysize(a,2)) -size(a::Array{<:Any,N}) where {N} = (@_inline_meta; ntuple(M -> size(a, M), Val(N))::Dims) +size(a::Array{<:Any,N}) where {N} = (@inline; ntuple(M -> size(a, M), Val(N))::Dims) asize_from(a::Array, n) = n > ndims(a) ? () : (arraysize(a,n), asize_from(a, n+1)...) @@ -174,7 +174,7 @@ isbitsunion(u::Union) = allocatedinline(u) isbitsunion(x) = false function _unsetindex!(A::Array{T}, i::Int) where {T} - @_inline_meta + @inline @boundscheck checkbounds(A, i) t = @_gc_preserve_begin A p = Ptr{Ptr{Cvoid}}(pointer(A, i)) @@ -217,7 +217,7 @@ elsize(::Type{<:Array{T}}) where {T} = aligned_sizeof(T) sizeof(a::Array) = Core.sizeof(a) function isassigned(a::Array, i::Int...) - @_inline_meta + @inline ii = (_sub2ind(size(a), i...) % UInt) - 1 @boundscheck ii < length(a) % UInt || return false ccall(:jl_array_isassigned, Cint, (Any, UInt), a, ii) == 1 @@ -336,7 +336,7 @@ end # occurs, see discussion in #27874. # It is also mitigated by using a constant string. function _throw_argerror() - @_noinline_meta + @noinline throw(ArgumentError("Number of elements to copy must be nonnegative.")) end @@ -408,10 +408,10 @@ function getindex(::Type{T}, vals...) where T return a end -getindex(::Type{T}) where {T} = (@_inline_meta; Vector{T}()) -getindex(::Type{T}, x) where {T} = (@_inline_meta; a = Vector{T}(undef, 1); @inbounds a[1] = x; a) -getindex(::Type{T}, x, y) where {T} = (@_inline_meta; a = Vector{T}(undef, 2); @inbounds (a[1] = x; a[2] = y); a) -getindex(::Type{T}, x, y, z) where {T} = (@_inline_meta; a = Vector{T}(undef, 3); @inbounds (a[1] = x; a[2] = y; a[3] = z); a) +getindex(::Type{T}) where {T} = (@inline; Vector{T}()) +getindex(::Type{T}, x) where {T} = (@inline; a = Vector{T}(undef, 1); @inbounds a[1] = x; a) +getindex(::Type{T}, x, y) where {T} = (@inline; a = Vector{T}(undef, 2); @inbounds (a[1] = x; a[2] = y); a) +getindex(::Type{T}, x, y, z) where {T} = (@inline; a = Vector{T}(undef, 3); @inbounds (a[1] = x; a[2] = y; a[3] = z); a) function getindex(::Type{Any}, @nospecialize vals...) a = Vector{Any}(undef, length(vals)) @@ -804,7 +804,7 @@ function collect_to_with_first!(dest, v1, itr, st) end function setindex_widen_up_to(dest::AbstractArray{T}, el, i) where T - @_inline_meta + @inline new = similar(dest, promote_typejoin(T, typeof(el))) f = first(LinearIndices(dest)) copyto!(new, first(LinearIndices(new)), dest, f, i-f) @@ -840,7 +840,7 @@ function grow_to!(dest, itr) end function push_widen(dest, el) - @_inline_meta + @inline new = sizehint!(empty(dest, promote_typejoin(eltype(dest), typeof(el))), length(dest)) if new isa AbstractSet # TODO: merge back these two branches when copy! is re-enabled for sets/vectors @@ -870,7 +870,7 @@ end ## Iteration ## -iterate(A::Array, i=1) = (@_inline_meta; (i % UInt) - 1 < length(A) ? (@inbounds A[i], i + 1) : nothing) +iterate(A::Array, i=1) = (@inline; (i % UInt) - 1 < length(A) ? (@inbounds A[i], i + 1) : nothing) ## Indexing: getindex ## @@ -897,11 +897,11 @@ function getindex end # This is more complicated than it needs to be in order to get Win64 through bootstrap @eval getindex(A::Array, i1::Int) = arrayref($(Expr(:boundscheck)), A, i1) -@eval getindex(A::Array, i1::Int, i2::Int, I::Int...) = (@_inline_meta; arrayref($(Expr(:boundscheck)), A, i1, i2, I...)) +@eval getindex(A::Array, i1::Int, i2::Int, I::Int...) = (@inline; arrayref($(Expr(:boundscheck)), A, i1, i2, I...)) # Faster contiguous indexing using copyto! for AbstractUnitRange and Colon function getindex(A::Array, I::AbstractUnitRange{<:Integer}) - @_inline_meta + @inline @boundscheck checkbounds(A, I) lI = length(I) X = similar(A, axes(I)) @@ -940,7 +940,7 @@ function setindex! end @eval setindex!(A::Array{T}, x, i1::Int) where {T} = arrayset($(Expr(:boundscheck)), A, convert(T,x)::T, i1) @eval setindex!(A::Array{T}, x, i1::Int, i2::Int, I::Int...) where {T} = - (@_inline_meta; arrayset($(Expr(:boundscheck)), A, convert(T,x)::T, i1, i2, I...)) + (@inline; arrayset($(Expr(:boundscheck)), A, convert(T,x)::T, i1, i2, I...)) # This is redundant with the abstract fallbacks but needed and helpful for bootstrap function setindex!(A::Array, X::AbstractArray, I::AbstractVector{Int}) @@ -960,7 +960,7 @@ end # Faster contiguous setindex! with copyto! function setindex!(A::Array{T}, X::Array{T}, I::AbstractUnitRange{Int}) where T - @_inline_meta + @inline @boundscheck checkbounds(A, I) lI = length(I) @boundscheck setindex_shape_check(X, lI) @@ -970,7 +970,7 @@ function setindex!(A::Array{T}, X::Array{T}, I::AbstractUnitRange{Int}) where T return A end function setindex!(A::Array{T}, X::Array{T}, c::Colon) where T - @_inline_meta + @inline lI = length(A) @boundscheck setindex_shape_check(X, lI) if lI > 0 diff --git a/base/boot.jl b/base/boot.jl index af66e471ae1d0e..ee1370bf5dff18 100644 --- a/base/boot.jl +++ b/base/boot.jl @@ -267,20 +267,15 @@ struct ErrorException <: Exception msg::AbstractString end -macro _inline_meta() - Expr(:meta, :inline) -end - -macro _noinline_meta() - Expr(:meta, :noinline) -end +macro inline() Expr(:meta, :inline) end +macro noinline() Expr(:meta, :noinline) end struct BoundsError <: Exception a::Any i::Any BoundsError() = new() - BoundsError(@nospecialize(a)) = (@_noinline_meta; new(a)) - BoundsError(@nospecialize(a), i) = (@_noinline_meta; new(a,i)) + BoundsError(@nospecialize(a)) = (@noinline; new(a)) + BoundsError(@nospecialize(a), i) = (@noinline; new(a,i)) end struct DivideError <: Exception end struct OutOfMemoryError <: Exception end @@ -298,8 +293,8 @@ struct InterruptException <: Exception end struct DomainError <: Exception val msg::AbstractString - DomainError(@nospecialize(val)) = (@_noinline_meta; new(val, "")) - DomainError(@nospecialize(val), @nospecialize(msg)) = (@_noinline_meta; new(val, msg)) + DomainError(@nospecialize(val)) = (@noinline; new(val, "")) + DomainError(@nospecialize(val), @nospecialize(msg)) = (@noinline; new(val, msg)) end struct TypeError <: Exception # `func` is the name of the builtin function that encountered a type error, @@ -320,7 +315,7 @@ struct InexactError <: Exception func::Symbol T # Type val - InexactError(f::Symbol, @nospecialize(T), @nospecialize(val)) = (@_noinline_meta; new(f, T, val)) + InexactError(f::Symbol, @nospecialize(T), @nospecialize(val)) = (@noinline; new(f, T, val)) end struct OverflowError <: Exception msg::AbstractString @@ -609,26 +604,26 @@ eval(Core, :(NamedTuple{names,T}(args::T) where {names, T <: Tuple} = import .Intrinsics: eq_int, trunc_int, lshr_int, sub_int, shl_int, bitcast, sext_int, zext_int, and_int -throw_inexacterror(f::Symbol, ::Type{T}, val) where {T} = (@_noinline_meta; throw(InexactError(f, T, val))) +throw_inexacterror(f::Symbol, ::Type{T}, val) where {T} = (@noinline; throw(InexactError(f, T, val))) function is_top_bit_set(x) - @_inline_meta + @inline eq_int(trunc_int(UInt8, lshr_int(x, sub_int(shl_int(sizeof(x), 3), 1))), trunc_int(UInt8, 1)) end function is_top_bit_set(x::Union{Int8,UInt8}) - @_inline_meta + @inline eq_int(lshr_int(x, 7), trunc_int(typeof(x), 1)) end function check_top_bit(::Type{To}, x) where {To} - @_inline_meta + @inline is_top_bit_set(x) && throw_inexacterror(:check_top_bit, To, x) x end function checked_trunc_sint(::Type{To}, x::From) where {To,From} - @_inline_meta + @inline y = trunc_int(To, x) back = sext_int(From, y) eq_int(x, back) || throw_inexacterror(:trunc, To, x) @@ -636,7 +631,7 @@ function checked_trunc_sint(::Type{To}, x::From) where {To,From} end function checked_trunc_uint(::Type{To}, x::From) where {To,From} - @_inline_meta + @inline y = trunc_int(To, x) back = zext_int(From, y) eq_int(x, back) || throw_inexacterror(:trunc, To, x) diff --git a/base/checked.jl b/base/checked.jl index ba23d4c5acd2bb..ad92a44e1e5bca 100644 --- a/base/checked.jl +++ b/base/checked.jl @@ -13,7 +13,7 @@ import Core.Intrinsics: 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, ..checked_length +import ..no_op_err, ..@inline, ..@noinline, ..checked_length # define promotion behavior for checked operations checked_add(x::Integer, y::Integer) = checked_add(promote(x,y)...) @@ -86,7 +86,7 @@ The overflow protection may impose a perceptible performance penalty. function checked_neg(x::T) where T<:Integer checked_sub(T(0), x) end -throw_overflowerr_negation(x) = (@_noinline_meta; +throw_overflowerr_negation(x) = (@noinline; throw(OverflowError(Base.invokelatest(string, "checked arithmetic: cannot compute -x for x = ", x, "::", typeof(x))))) if BrokenSignedInt != Union{} function checked_neg(x::BrokenSignedInt) @@ -150,7 +150,7 @@ end end -throw_overflowerr_binaryop(op, x, y) = (@_noinline_meta; +throw_overflowerr_binaryop(op, x, y) = (@noinline; throw(OverflowError(Base.invokelatest(string, x, " ", op, " ", y, " overflowed for type ", typeof(x))))) """ @@ -161,7 +161,7 @@ Calculates `x+y`, checking for overflow errors where applicable. The overflow protection may impose a perceptible performance penalty. """ function checked_add(x::T, y::T) where T<:Integer - @_inline_meta + @inline z, b = add_with_overflow(x, y) b && throw_overflowerr_binaryop(:+, x, y) z @@ -218,7 +218,7 @@ Calculates `x-y`, checking for overflow errors where applicable. The overflow protection may impose a perceptible performance penalty. """ function checked_sub(x::T, y::T) where T<:Integer - @_inline_meta + @inline z, b = sub_with_overflow(x, y) b && throw_overflowerr_binaryop(:-, x, y) z @@ -283,7 +283,7 @@ Calculates `x*y`, checking for overflow errors where applicable. The overflow protection may impose a perceptible performance penalty. """ function checked_mul(x::T, y::T) where T<:Integer - @_inline_meta + @inline z, b = mul_with_overflow(x, y) b && throw_overflowerr_binaryop(:*, x, y) z diff --git a/base/compiler/compiler.jl b/base/compiler/compiler.jl index 5882c967dbf145..3f3883eb4647f3 100644 --- a/base/compiler/compiler.jl +++ b/base/compiler/compiler.jl @@ -22,14 +22,10 @@ eval(m, x) = Core.eval(m, x) include(x) = Core.include(Compiler, x) include(mod, x) = Core.include(mod, x) -# The real @inline macro is not available until after array.jl, so this -# internal macro splices the meta Expr directly into the function body. -macro _inline_meta() - Expr(:meta, :inline) -end -macro _noinline_meta() - Expr(:meta, :noinline) -end +# The @inline/@noinline macros that can be applied to a function declaration are not available +# until after array.jl, and so we will mark them within a function body instead. +macro inline() Expr(:meta, :inline) end +macro noinline() Expr(:meta, :noinline) end # essential files and libraries include("essentials.jl") @@ -88,9 +84,9 @@ using .Iterators: Flatten, Filter, product # for generators include("namedtuple.jl") ntuple(f, ::Val{0}) = () -ntuple(f, ::Val{1}) = (@_inline_meta; (f(1),)) -ntuple(f, ::Val{2}) = (@_inline_meta; (f(1), f(2))) -ntuple(f, ::Val{3}) = (@_inline_meta; (f(1), f(2), f(3))) +ntuple(f, ::Val{1}) = (@inline; (f(1),)) +ntuple(f, ::Val{2}) = (@inline; (f(1), f(2))) +ntuple(f, ::Val{3}) = (@inline; (f(1), f(2), f(3))) ntuple(f, ::Val{n}) where {n} = ntuple(f, n::Int) ntuple(f, n) = (Any[f(i) for i = 1:n]...,) diff --git a/base/deprecated.jl b/base/deprecated.jl index 77dab6d701772f..1f54940c4b5de2 100644 --- a/base/deprecated.jl +++ b/base/deprecated.jl @@ -263,3 +263,10 @@ end @deprecate catch_stack(task=current_task(); include_bt=true) current_exceptions(task; backtrace=include_bt) false # END 1.7 deprecations + +# BEGIN 1.8 deprecations + +@deprecate var"@_inline_meta" var"@inline" false +@deprecate var"@_noinline_meta" var"@noinline" false + +# END 1.8 deprecations diff --git a/base/error.jl b/base/error.jl index 9a6c6a5581b6fb..653f4f9760edff 100644 --- a/base/error.jl +++ b/base/error.jl @@ -38,7 +38,7 @@ error(s::AbstractString) = throw(ErrorException(s)) Raise an `ErrorException` with the given message. """ function error(s::Vararg{Any,N}) where {N} - @_noinline_meta + @noinline throw(ErrorException(Main.Base.string(s...))) end @@ -105,7 +105,7 @@ end Get a backtrace object for the current program point. """ function backtrace() - @_noinline_meta + @noinline # skip frame for backtrace(). Note that for this to work properly, # backtrace() itself must not be interpreted nor inlined. skip = 1 @@ -159,7 +159,7 @@ end ## keyword arg lowering generates calls to this ## function kwerr(kw, args::Vararg{Any,N}) where {N} - @_noinline_meta + @noinline throw(MethodError(typeof(args[1]).name.mt.kwsorter, (kw,args...))) end diff --git a/base/essentials.jl b/base/essentials.jl index 9bdf306cac43ee..5280252f1946a2 100644 --- a/base/essentials.jl +++ b/base/essentials.jl @@ -331,7 +331,7 @@ function typename(a::Union) end typename(union::UnionAll) = typename(union.body) -_tuple_error(T::Type, x) = (@_noinline_meta; throw(MethodError(convert, (T, x)))) +_tuple_error(T::Type, x) = (@noinline; throw(MethodError(convert, (T, x)))) convert(::Type{T}, x::T) where {T<:Tuple} = x function convert(::Type{T}, x::NTuple{N,Any}) where {N, T<:Tuple} @@ -340,7 +340,7 @@ function convert(::Type{T}, x::NTuple{N,Any}) where {N, T<:Tuple} if typeintersect(NTuple{N,Any}, T) === Union{} _tuple_error(T, x) end - cvt1(n) = (@_inline_meta; convert(fieldtype(T, n), getfield(x, n, #=boundscheck=#false))) + cvt1(n) = (@inline; convert(fieldtype(T, n), getfield(x, n, #=boundscheck=#false))) return ntuple(cvt1, Val(N))::NTuple{N,Any} end diff --git a/base/experimental.jl b/base/experimental.jl index 232d2efd11d211..421e6861bcaab0 100644 --- a/base/experimental.jl +++ b/base/experimental.jl @@ -29,9 +29,9 @@ Base.IndexStyle(::Type{<:Const}) = IndexLinear() Base.size(C::Const) = size(C.a) Base.axes(C::Const) = axes(C.a) @eval Base.getindex(A::Const, i1::Int) = - (Base.@_inline_meta; Core.const_arrayref($(Expr(:boundscheck)), A.a, i1)) + (Base.@inline; Core.const_arrayref($(Expr(:boundscheck)), A.a, i1)) @eval Base.getindex(A::Const, i1::Int, i2::Int, I::Int...) = - (Base.@_inline_meta; Core.const_arrayref($(Expr(:boundscheck)), A.a, i1, i2, I...)) + (Base.@inline; Core.const_arrayref($(Expr(:boundscheck)), A.a, i1, i2, I...)) """ @aliasscope expr diff --git a/base/expr.jl b/base/expr.jl index b91181ea2dfe7e..f583a58f78dc5c 100644 --- a/base/expr.jl +++ b/base/expr.jl @@ -213,7 +213,6 @@ end macro inline(ex) esc(isa(ex, Expr) ? pushmeta!(ex, :inline) : ex) end -macro inline() Expr(:meta, :inline) end """ @noinline @@ -251,7 +250,6 @@ end macro noinline(ex) esc(isa(ex, Expr) ? pushmeta!(ex, :noinline) : ex) end -macro noinline() Expr(:meta, :noinline) end """ @pure ex diff --git a/base/gcutils.jl b/base/gcutils.jl index e74752f4f66262..7010f8fa7d2f1b 100644 --- a/base/gcutils.jl +++ b/base/gcutils.jl @@ -51,7 +51,7 @@ function finalizer(@nospecialize(f), @nospecialize(o)) end function finalizer(f::Ptr{Cvoid}, o::T) where T - @_inline_meta + @inline if !ismutable(o) error("objects of type ", typeof(o), " cannot be finalized") end @@ -117,7 +117,7 @@ another Task or thread. enable_finalizers(on::Bool) = on ? enable_finalizers() : disable_finalizers() function enable_finalizers() - Base.@_inline_meta + Base.@inline ccall(:jl_gc_enable_finalizers_internal, Cvoid, ()) if unsafe_load(cglobal(:jl_gc_have_pending_finalizers, Cint)) != 0 ccall(:jl_gc_run_pending_finalizers, Cvoid, (Ptr{Cvoid},), C_NULL) @@ -125,7 +125,7 @@ function enable_finalizers() end function disable_finalizers() - Base.@_inline_meta + Base.@inline ccall(:jl_gc_disable_finalizers_internal, Cvoid, ()) end diff --git a/base/generator.jl b/base/generator.jl index e5b3e46f883617..1317aaf5223e05 100644 --- a/base/generator.jl +++ b/base/generator.jl @@ -40,7 +40,7 @@ Generator(::Type{T}, iter::I) where {T,I} = Generator{I,Type{T}}(T, iter) Generator(::Type{T}, I1, I2, Is...) where {T} = Generator(a->T(a...), zip(I1, I2, Is...)) function iterate(g::Generator, s...) - @_inline_meta + @inline y = iterate(g.iter, s...) y === nothing && return nothing y = y::Tuple{Any, Any} # try to give inference some idea of what to expect about the behavior of the next line diff --git a/base/indices.jl b/base/indices.jl index 817d9d435522bc..28028f23c72a36 100644 --- a/base/indices.jl +++ b/base/indices.jl @@ -321,16 +321,16 @@ which they index. To support those cases, `to_indices(A, I)` calls given tuple of indices and the dimensional indices of `A` in tandem. As such, not all index types are guaranteed to propagate to `Base.to_index`. """ -to_indices(A, I::Tuple) = (@_inline_meta; to_indices(A, axes(A), I)) -to_indices(A, I::Tuple{Any}) = (@_inline_meta; to_indices(A, (eachindex(IndexLinear(), A),), I)) +to_indices(A, I::Tuple) = (@inline; to_indices(A, axes(A), I)) +to_indices(A, I::Tuple{Any}) = (@inline; to_indices(A, (eachindex(IndexLinear(), A),), I)) # In simple cases, we know that we don't need to use axes(A), optimize those. # Having this here avoids invalidations from multidimensional.jl: to_indices(A, I::Tuple{Vararg{Union{Integer, CartesianIndex}}}) to_indices(A, I::Tuple{}) = () to_indices(A, I::Tuple{Vararg{Int}}) = I -to_indices(A, I::Tuple{Vararg{Integer}}) = (@_inline_meta; to_indices(A, (), I)) +to_indices(A, I::Tuple{Vararg{Integer}}) = (@inline; to_indices(A, (), I)) to_indices(A, inds, ::Tuple{}) = () to_indices(A, inds, I::Tuple{Any, Vararg{Any}}) = - (@_inline_meta; (to_index(A, I[1]), to_indices(A, _maybetail(inds), tail(I))...)) + (@inline; (to_index(A, I[1]), to_indices(A, _maybetail(inds), tail(I))...)) _maybetail(::Tuple{}) = () _maybetail(t::Tuple) = tail(t) @@ -360,9 +360,9 @@ first(S::Slice) = first(S.indices) last(S::Slice) = last(S.indices) size(S::Slice) = (length(S.indices),) length(S::Slice) = 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) +getindex(S::Slice, i::Int) = (@inline; @boundscheck checkbounds(S, i); i) +getindex(S::Slice, i::AbstractUnitRange{<:Integer}) = (@inline; @boundscheck checkbounds(S, i); i) +getindex(S::Slice, i::StepRange{<:Integer}) = (@inline; @boundscheck checkbounds(S, i); i) show(io::IO, r::Slice) = print(io, "Base.Slice(", r.indices, ")") iterate(S::Slice, s...) = iterate(S.indices, s...) @@ -388,15 +388,15 @@ first(S::IdentityUnitRange) = first(S.indices) last(S::IdentityUnitRange) = last(S.indices) size(S::IdentityUnitRange) = (length(S.indices),) length(S::IdentityUnitRange) = 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) +getindex(S::IdentityUnitRange, i::Int) = (@inline; @boundscheck checkbounds(S, i); i) +getindex(S::IdentityUnitRange, i::AbstractUnitRange{<:Integer}) = (@inline; @boundscheck checkbounds(S, i); i) +getindex(S::IdentityUnitRange, i::StepRange{<:Integer}) = (@inline; @boundscheck checkbounds(S, i); i) show(io::IO, r::IdentityUnitRange) = print(io, "Base.IdentityUnitRange(", r.indices, ")") iterate(S::IdentityUnitRange, s...) = iterate(S.indices, s...) # For OneTo, the values and indices of the values are identical, so this may be defined in Base. # In general such an indexing operation would produce offset ranges -getindex(S::OneTo, I::IdentityUnitRange{<:AbstractUnitRange{<:Integer}}) = (@_inline_meta; @boundscheck checkbounds(S, I); I) +getindex(S::OneTo, I::IdentityUnitRange{<:AbstractUnitRange{<:Integer}}) = (@inline; @boundscheck checkbounds(S, I); I) """ LinearIndices(A::AbstractArray) @@ -475,12 +475,12 @@ IndexStyle(::Type{<:LinearIndices}) = IndexLinear() axes(iter::LinearIndices) = map(axes1, iter.indices) size(iter::LinearIndices) = map(length, iter.indices) function getindex(iter::LinearIndices, i::Int) - @_inline_meta + @inline @boundscheck checkbounds(iter, i) i end function getindex(iter::LinearIndices, i::AbstractRange{<:Integer}) - @_inline_meta + @inline @boundscheck checkbounds(iter, i) @inbounds isa(iter, LinearIndices{1}) ? iter.indices[1][i] : (first(iter):last(iter))[i] end @@ -491,6 +491,6 @@ iterate(iter::LinearIndices, i=1) = i > length(iter) ? nothing : (i, i+1) # Needed since firstindex and lastindex are defined in terms of LinearIndices first(iter::LinearIndices) = 1 -first(iter::LinearIndices{1}) = (@_inline_meta; first(axes1(iter.indices[1]))) -last(iter::LinearIndices) = (@_inline_meta; length(iter)) -last(iter::LinearIndices{1}) = (@_inline_meta; last(axes1(iter.indices[1]))) +first(iter::LinearIndices{1}) = (@inline; first(axes1(iter.indices[1]))) +last(iter::LinearIndices) = (@inline; length(iter)) +last(iter::LinearIndices{1}) = (@inline; last(axes1(iter.indices[1]))) diff --git a/base/loading.jl b/base/loading.jl index be835677affdbb..bec6596b2142ad 100644 --- a/base/loading.jl +++ b/base/loading.jl @@ -1252,7 +1252,7 @@ Base.include # defined in Base.jl # Full include() implementation which is used after bootstrap function _include(mapexpr::Function, mod::Module, _path::AbstractString) - @_noinline_meta # Workaround for module availability in _simplify_include_frames + @noinline # Workaround for module availability in _simplify_include_frames path, prev = _include_dependency(mod, _path) for callback in include_callbacks # to preserve order, must come before eval in include_string invokelatest(callback, mod, path) diff --git a/base/multidimensional.jl b/base/multidimensional.jl index 9694a8b9da650a..c8f06309b9a1a8 100644 --- a/base/multidimensional.jl +++ b/base/multidimensional.jl @@ -651,7 +651,7 @@ using .IteratorsMD ## Bounds-checking with CartesianIndex # Disallow linear indexing with CartesianIndex function checkbounds(::Type{Bool}, A::AbstractArray, i::Union{CartesianIndex, AbstractArray{<:CartesianIndex}}) - @_inline_meta + @inline checkbounds_indices(Bool, axes(A), (i,)) end @@ -880,7 +880,7 @@ end function _generate_unsafe_getindex!_body(N::Int) quote - @_inline_meta + @inline D = eachindex(dest) Dy = iterate(D) @inbounds @nloops $N j d->I[d] begin @@ -913,7 +913,7 @@ end ## setindex! ## function _setindex!(l::IndexStyle, A::AbstractArray, x, I::Union{Real, AbstractArray}...) - @_inline_meta + @inline @boundscheck checkbounds(A, I...) _unsafe_setindex!(l, _maybe_reshape(l, A, I...), x, I...) A diff --git a/base/ntuple.jl b/base/ntuple.jl index a5608dfa927c33..6f70b494812230 100644 --- a/base/ntuple.jl +++ b/base/ntuple.jl @@ -32,22 +32,22 @@ julia> ntuple(i -> 2*i, 4) end function _ntuple(f::F, n) where F - @_noinline_meta + @noinline (n >= 0) || throw(ArgumentError(string("tuple length should be ≥ 0, got ", n))) ([f(i) for i = 1:n]...,) end function ntupleany(f, n) - @_noinline_meta + @noinline (n >= 0) || throw(ArgumentError(string("tuple length should be ≥ 0, got ", n))) (Any[f(i) for i = 1:n]...,) end # inferrable ntuple (enough for bootstrapping) ntuple(f, ::Val{0}) = () -ntuple(f, ::Val{1}) = (@_inline_meta; (f(1),)) -ntuple(f, ::Val{2}) = (@_inline_meta; (f(1), f(2))) -ntuple(f, ::Val{3}) = (@_inline_meta; (f(1), f(2), f(3))) +ntuple(f, ::Val{1}) = (@inline; (f(1),)) +ntuple(f, ::Val{2}) = (@inline; (f(1), f(2))) +ntuple(f, ::Val{3}) = (@inline; (f(1), f(2), f(3))) """ ntuple(f, ::Val{N}) diff --git a/base/number.jl b/base/number.jl index 852c8b715af1d7..d3bf14d566250f 100644 --- a/base/number.jl +++ b/base/number.jl @@ -94,12 +94,12 @@ keys(::Number) = OneTo(1) getindex(x::Number) = x function getindex(x::Number, i::Integer) - @_inline_meta + @inline @boundscheck i == 1 || throw(BoundsError()) x end function getindex(x::Number, I::Integer...) - @_inline_meta + @inline @boundscheck all(isone, I) || throw(BoundsError()) x end diff --git a/base/operators.jl b/base/operators.jl index 8c1a024dc48e03..74cf3e95145a6a 100644 --- a/base/operators.jl +++ b/base/operators.jl @@ -717,13 +717,13 @@ julia> bitstring(Int8(12)) See also [`>>`](@ref), [`>>>`](@ref), [`exp2`](@ref), [`ldexp`](@ref). """ function <<(x::Integer, c::Integer) - @_inline_meta + @inline typemin(Int) <= c <= typemax(Int) && return x << (c % Int) (x >= 0 || c >= 0) && return zero(x) << 0 # for type stability oftype(x, -1) end function <<(x::Integer, c::Unsigned) - @_inline_meta + @inline if c isa UInt throw(MethodError(<<, (x, c))) end @@ -762,7 +762,7 @@ julia> bitstring(Int8(-4)) See also [`>>>`](@ref), [`<<`](@ref). """ function >>(x::Integer, c::Integer) - @_inline_meta + @inline if c isa UInt throw(MethodError(>>, (x, c))) end @@ -800,11 +800,11 @@ is equivalent to [`>>`](@ref). See also [`>>`](@ref), [`<<`](@ref). """ function >>>(x::Integer, c::Integer) - @_inline_meta + @inline typemin(Int) <= c <= typemax(Int) ? x >>> (c % Int) : zero(x) >>> 0 end function >>>(x::Integer, c::Unsigned) - @_inline_meta + @inline if c isa UInt throw(MethodError(>>>, (x, c))) end diff --git a/base/pointer.jl b/base/pointer.jl index b315e589ffd9a6..b9475724f76374 100644 --- a/base/pointer.jl +++ b/base/pointer.jl @@ -142,7 +142,7 @@ stable memory addresses. See also [`unsafe_pointer_to_objref`](@ref). """ function pointer_from_objref(@nospecialize(x)) - @_inline_meta + @inline ismutable(x) || error("pointer_from_objref cannot be used on immutable objects") ccall(:jl_value_ptr, Ptr{Cvoid}, (Any,), x) end diff --git a/base/promotion.jl b/base/promotion.jl index 6d216876ce0478..cae7d07f06da6c 100644 --- a/base/promotion.jl +++ b/base/promotion.jl @@ -233,7 +233,7 @@ function promote_type end promote_type() = Bottom promote_type(T) = T -promote_type(T, S, U, V...) = (@_inline_meta; promote_type(T, promote_type(S, U, V...))) +promote_type(T, S, U, V...) = (@inline; promote_type(T, promote_type(S, U, V...))) promote_type(::Type{Bottom}, ::Type{Bottom}) = Bottom promote_type(::Type{T}, ::Type{T}) where {T} = T @@ -241,7 +241,7 @@ promote_type(::Type{T}, ::Type{Bottom}) where {T} = T promote_type(::Type{Bottom}, ::Type{T}) where {T} = T function promote_type(::Type{T}, ::Type{S}) where {T,S} - @_inline_meta + @inline # Try promote_rule in both orders. Typically only one is defined, # and there is a fallback returning Bottom below, so the common case is # promote_type(T, S) => @@ -261,10 +261,10 @@ function promote_rule end promote_rule(::Type{<:Any}, ::Type{<:Any}) = Bottom -promote_result(::Type{<:Any},::Type{<:Any},::Type{T},::Type{S}) where {T,S} = (@_inline_meta; promote_type(T,S)) +promote_result(::Type{<:Any},::Type{<:Any},::Type{T},::Type{S}) where {T,S} = (@inline; promote_type(T,S)) # If no promote_rule is defined, both directions give Bottom. In that # case use typejoin on the original types instead. -promote_result(::Type{T},::Type{S},::Type{Bottom},::Type{Bottom}) where {T,S} = (@_inline_meta; typejoin(T, S)) +promote_result(::Type{T},::Type{S},::Type{Bottom},::Type{Bottom}) where {T,S} = (@inline; typejoin(T, S)) """ promote(xs...) @@ -283,19 +283,19 @@ julia> promote(Int8(1), Float16(4.5), Float32(4.1)) function promote end function _promote(x::T, y::S) where {T,S} - @_inline_meta + @inline R = promote_type(T, S) return (convert(R, x), convert(R, y)) end promote_typeof(x) = typeof(x) -promote_typeof(x, xs...) = (@_inline_meta; promote_type(typeof(x), promote_typeof(xs...))) +promote_typeof(x, xs...) = (@inline; promote_type(typeof(x), promote_typeof(xs...))) function _promote(x, y, z) - @_inline_meta + @inline R = promote_typeof(x, y, z) return (convert(R, x), convert(R, y), convert(R, z)) end function _promote(x, y, zs...) - @_inline_meta + @inline R = promote_typeof(x, y, zs...) return (convert(R, x), convert(R, y), convert(Tuple{Vararg{R}}, zs)...) end @@ -307,13 +307,13 @@ promote() = () promote(x) = (x,) function promote(x, y) - @_inline_meta + @inline px, py = _promote(x, y) not_sametype((x,y), (px,py)) px, py end function promote(x, y, z) - @_inline_meta + @inline px, py, pz = _promote(x, y, z) not_sametype((x,y,z), (px,py,pz)) px, py, pz @@ -331,7 +331,7 @@ not_sametype(x::T, y::T) where {T} = sametype_error(x) not_sametype(x, y) = nothing function sametype_error(input) - @_noinline_meta + @noinline error("promotion of types ", join(map(x->string(typeof(x)), input), ", ", " and "), " failed to change any arguments") diff --git a/base/range.jl b/base/range.jl index f4bf71c4f70c35..33777484af3efe 100644 --- a/base/range.jl +++ b/base/range.jl @@ -404,7 +404,7 @@ unitrange(x) = UnitRange(x) if isdefined(Main, :Base) # Constant-fold-able indexing into tuples to functionally expose Base.tail and Base.front function getindex(@nospecialize(t::Tuple), r::AbstractUnitRange) - @_inline_meta + @inline require_one_based_indexing(r) if length(r) <= 10 return ntuple(i -> t[i + first(r) - 1], length(r)) @@ -430,15 +430,15 @@ be 1. struct OneTo{T<:Integer} <: AbstractUnitRange{T} stop::T function OneTo{T}(stop) where {T<:Integer} - throwbool(r) = (@_noinline_meta; throw(ArgumentError("invalid index: $r of type Bool"))) + throwbool(r) = (@noinline; throw(ArgumentError("invalid index: $r of type Bool"))) T === Bool && throwbool(stop) return new(max(zero(T), stop)) end function OneTo{T}(r::AbstractRange) where {T<:Integer} - throwstart(r) = (@_noinline_meta; throw(ArgumentError("first element must be 1, got $(first(r))"))) - throwstep(r) = (@_noinline_meta; throw(ArgumentError("step must be 1, got $(step(r))"))) - throwbool(r) = (@_noinline_meta; throw(ArgumentError("invalid index: $r of type Bool"))) + throwstart(r) = (@noinline; throw(ArgumentError("first element must be 1, got $(first(r))"))) + throwstep(r) = (@noinline; throw(ArgumentError("step must be 1, got $(step(r))"))) + throwbool(r) = (@noinline; throw(ArgumentError("invalid index: $r of type Bool"))) first(r) == 1 || throwstart(r) step(r) == 1 || throwstep(r) T === Bool && throwbool(r) @@ -733,7 +733,7 @@ function length(r::OrdinalRange{T}) where T end function length(r::AbstractUnitRange{T}) where T - @_inline_meta + @inline a = last(r) - first(r) # even when isempty, by construction (with overflow) return Integer(a + oneunit(a)) end @@ -857,7 +857,7 @@ copy(r::AbstractRange) = r ## iteration function iterate(r::Union{StepRangeLen,LinRange}, i::Integer=zero(length(r))) - @_inline_meta + @inline i += oneunit(i) length(r) < i && return nothing unsafe_getindex(r, i), i @@ -866,7 +866,7 @@ end iterate(r::OrdinalRange) = isempty(r) ? nothing : (first(r), first(r)) function iterate(r::OrdinalRange{T}, i) where {T} - @_inline_meta + @inline i == last(r) && return nothing next = convert(T, i + step(r)) (next, next) @@ -877,7 +877,7 @@ end _in_unit_range(v::UnitRange, val, i::Integer) = i > 0 && val <= v.stop && val >= v.start function getindex(v::UnitRange{T}, i::Integer) where T - @_inline_meta + @inline i isa Bool && throw(ArgumentError("invalid index: $i of type Bool")) val = convert(T, v.start + (i - 1)) @boundscheck _in_unit_range(v, val, i) || throw_boundserror(v, i) @@ -888,7 +888,7 @@ const OverflowSafe = Union{Bool,Int8,Int16,Int32,Int64,Int128, UInt8,UInt16,UInt32,UInt64,UInt128} function getindex(v::UnitRange{T}, i::Integer) where {T<:OverflowSafe} - @_inline_meta + @inline i isa Bool && throw(ArgumentError("invalid index: $i of type Bool")) val = v.start + (i - 1) @boundscheck _in_unit_range(v, val, i) || throw_boundserror(v, i) @@ -896,14 +896,14 @@ function getindex(v::UnitRange{T}, i::Integer) where {T<:OverflowSafe} end function getindex(v::OneTo{T}, i::Integer) where T - @_inline_meta + @inline i isa Bool && throw(ArgumentError("invalid index: $i of type Bool")) @boundscheck ((i > 0) & (i <= v.stop)) || throw_boundserror(v, i) convert(T, i) end function getindex(v::AbstractRange{T}, i::Integer) where T - @_inline_meta + @inline i isa Bool && throw(ArgumentError("invalid index: $i of type Bool")) ret = convert(T, first(v) + (i - 1)*step_hp(v)) ok = ifelse(step(v) > zero(step(v)), @@ -914,7 +914,7 @@ function getindex(v::AbstractRange{T}, i::Integer) where T end function getindex(r::Union{StepRangeLen,LinRange}, i::Integer) - @_inline_meta + @inline i isa Bool && throw(ArgumentError("invalid index: $i of type Bool")) @boundscheck checkbounds(r, i) unsafe_getindex(r, i) @@ -939,7 +939,7 @@ function unsafe_getindex(r::LinRange, i::Integer) end function lerpi(j::Integer, d::Integer, a::T, b::T) where T - @_inline_meta + @inline t = j/d T((1-t)*a + t*b) end @@ -947,7 +947,7 @@ end getindex(r::AbstractRange, ::Colon) = copy(r) function getindex(r::AbstractUnitRange, s::AbstractUnitRange{T}) where {T<:Integer} - @_inline_meta + @inline @boundscheck checkbounds(r, s) if T === Bool @@ -960,13 +960,13 @@ function getindex(r::AbstractUnitRange, s::AbstractUnitRange{T}) where {T<:Integ end function getindex(r::OneTo{T}, s::OneTo) where T - @_inline_meta + @inline @boundscheck checkbounds(r, s) OneTo(T(s.stop)) end function getindex(r::AbstractUnitRange, s::StepRange{T}) where {T<:Integer} - @_inline_meta + @inline @boundscheck checkbounds(r, s) if T === Bool @@ -978,7 +978,7 @@ function getindex(r::AbstractUnitRange, s::StepRange{T}) where {T<:Integer} end function getindex(r::StepRange, s::AbstractRange{T}) where {T<:Integer} - @_inline_meta + @inline @boundscheck checkbounds(r, s) if T === Bool @@ -1000,7 +1000,7 @@ function getindex(r::StepRange, s::AbstractRange{T}) where {T<:Integer} end function getindex(r::StepRangeLen{T}, s::OrdinalRange{S}) where {T, S<:Integer} - @_inline_meta + @inline @boundscheck checkbounds(r, s) len = length(s) @@ -1030,7 +1030,7 @@ function getindex(r::StepRangeLen{T}, s::OrdinalRange{S}) where {T, S<:Integer} end function getindex(r::LinRange{T}, s::OrdinalRange{S}) where {T, S<:Integer} - @_inline_meta + @inline @boundscheck checkbounds(r, s) len = length(s) diff --git a/base/rational.jl b/base/rational.jl index 1c83443d10df3a..0276e23bb5af5c 100644 --- a/base/rational.jl +++ b/base/rational.jl @@ -538,7 +538,7 @@ end # 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 + @inline f = first(r) l = last(r) return div(l.num - f.num + f.den, f.den) diff --git a/base/reinterpretarray.jl b/base/reinterpretarray.jl index 5ce0acf97ff5b2..ad1e8b26c4461d 100644 --- a/base/reinterpretarray.jl +++ b/base/reinterpretarray.jl @@ -12,25 +12,25 @@ struct ReinterpretArray{T,N,S,A<:AbstractArray{S},IsReshaped} <: AbstractArray{T writable::Bool function throwbits(S::Type, T::Type, U::Type) - @_noinline_meta + @noinline throw(ArgumentError("cannot reinterpret `$(S)` as `$(T)`, type `$(U)` is not a bits type")) end function throwsize0(S::Type, T::Type, msg) - @_noinline_meta + @noinline throw(ArgumentError("cannot reinterpret a zero-dimensional `$(S)` array to `$(T)` which is of a $msg size")) end global reinterpret function reinterpret(::Type{T}, a::A) where {T,N,S,A<:AbstractArray{S, N}} function thrownonint(S::Type, T::Type, dim) - @_noinline_meta + @noinline throw(ArgumentError(""" cannot reinterpret an `$(S)` array to `$(T)` whose first dimension has size `$(dim)`. The resulting array would have non-integral first dimension. """)) end function throwaxes1(S::Type, T::Type, ax1) - @_noinline_meta + @noinline throw(ArgumentError("cannot reinterpret a `$(S)` array to `$(T)` when the first axis is $ax1. Try reshaping first.")) end isbitstype(T) || throwbits(S, T, T) @@ -51,11 +51,11 @@ struct ReinterpretArray{T,N,S,A<:AbstractArray{S},IsReshaped} <: AbstractArray{T # With reshaping function reinterpret(::typeof(reshape), ::Type{T}, a::A) where {T,S,A<:AbstractArray{S}} function throwintmult(S::Type, T::Type) - @_noinline_meta + @noinline throw(ArgumentError("`reinterpret(reshape, T, a)` requires that one of `sizeof(T)` (got $(sizeof(T))) and `sizeof(eltype(a))` (got $(sizeof(S))) be an integer multiple of the other")) end function throwsize1(a::AbstractArray, T::Type) - @_noinline_meta + @noinline throw(ArgumentError("`reinterpret(reshape, $T, a)` where `eltype(a)` is $(eltype(a)) requires that `axes(a, 1)` (got $(axes(a, 1))) be equal to 1:$(sizeof(T) ÷ sizeof(eltype(a))) (from the ratio of element sizes)")) end isbitstype(T) || throwbits(S, T, T) diff --git a/base/reshapedarray.jl b/base/reshapedarray.jl index 1d40a00810e99a..cabe3c9d10a589 100644 --- a/base/reshapedarray.jl +++ b/base/reshapedarray.jl @@ -287,7 +287,7 @@ viewindexing(I::Tuple{Slice, ReshapedUnitRange, Vararg{ScalarIndex}}) = IndexLin viewindexing(I::Tuple{ReshapedRange, Vararg{ScalarIndex}}) = IndexLinear() compute_stride1(s, inds, I::Tuple{ReshapedRange, Vararg{Any}}) = s*step(I[1].parent) compute_offset1(parent::AbstractVector, stride1::Integer, I::Tuple{ReshapedRange}) = - (@_inline_meta; first(I[1]) - first(axes1(I[1]))*stride1) + (@inline; first(I[1]) - first(axes1(I[1]))*stride1) substrides(strds::NTuple{N,Int}, I::Tuple{ReshapedUnitRange, Vararg{Any}}) where N = (size_to_strides(strds[1], size(I[1])...)..., substrides(tail(strds), tail(I))...) unsafe_convert(::Type{Ptr{T}}, V::SubArray{T,N,P,<:Tuple{Vararg{Union{RangeIndex,ReshapedUnitRange}}}}) where {T,N,P} = diff --git a/base/set.jl b/base/set.jl index e2e6a83b0a4c5b..5faf72e3577649 100644 --- a/base/set.jl +++ b/base/set.jl @@ -761,7 +761,7 @@ replace(f::Callable, t::Tuple; count::Integer=typemax(Int)) = function _replace(t::Tuple, count::Int, old_new::Tuple{Vararg{Pair}}) _replace(t, count) do x - @_inline_meta + @inline for o_n in old_new isequal(first(o_n), x) && return last(o_n) end diff --git a/base/subarray.jl b/base/subarray.jl index 1524f0bb0950f3..ff2408bb48534a 100644 --- a/base/subarray.jl +++ b/base/subarray.jl @@ -17,22 +17,22 @@ struct SubArray{T,N,P,I,L} <: AbstractArray{T,N} offset1::Int # for linear indexing and pointer, only valid when L==true stride1::Int # used only for linear indexing function SubArray{T,N,P,I,L}(parent, indices, offset1, stride1) where {T,N,P,I,L} - @_inline_meta + @inline check_parent_index_match(parent, indices) new(parent, indices, offset1, stride1) end end # Compute the linear indexability of the indices, and combine it with the linear indexing of the parent function SubArray(parent::AbstractArray, indices::Tuple) - @_inline_meta + @inline SubArray(IndexStyle(viewindexing(indices), IndexStyle(parent)), parent, ensure_indexable(indices), index_dimsum(indices...)) end function SubArray(::IndexCartesian, parent::P, indices::I, ::NTuple{N,Any}) where {P,I,N} - @_inline_meta + @inline SubArray{eltype(P), N, P, I, false}(parent, indices, 0, 0) end function SubArray(::IndexLinear, parent::P, indices::I, ::NTuple{N,Any}) where {P,I,N} - @_inline_meta + @inline # Compute the stride and offset stride1 = compute_stride1(parent, indices) SubArray{eltype(P), N, P, I, true}(parent, indices, compute_offset1(parent, stride1, indices), stride1) @@ -46,9 +46,9 @@ check_parent_index_match(parent, ::NTuple{N, Bool}) where {N} = # This computes the linear indexing compatibility for a given tuple of indices viewindexing(I::Tuple{}) = IndexLinear() # Leading scalar indices simply increase the stride -viewindexing(I::Tuple{ScalarIndex, Vararg{Any}}) = (@_inline_meta; viewindexing(tail(I))) +viewindexing(I::Tuple{ScalarIndex, Vararg{Any}}) = (@inline; viewindexing(tail(I))) # Slices may begin a section which may be followed by any number of Slices -viewindexing(I::Tuple{Slice, Slice, Vararg{Any}}) = (@_inline_meta; viewindexing(tail(I))) +viewindexing(I::Tuple{Slice, Slice, Vararg{Any}}) = (@inline; viewindexing(tail(I))) # A UnitRange can follow Slices, but only if all other indices are scalar viewindexing(I::Tuple{Slice, AbstractUnitRange, Vararg{ScalarIndex}}) = IndexLinear() viewindexing(I::Tuple{Slice, Slice, Vararg{ScalarIndex}}) = IndexLinear() # disambiguate @@ -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(length, axes(V))) +size(V::SubArray) = (@inline; map(length, axes(V))) similar(V::SubArray, T::Type, dims::Dims) = similar(V.parent, T, dims) @@ -172,7 +172,7 @@ julia> view(2:5, 2:3) # returns a range as type is immutable ``` """ function view(A::AbstractArray, I::Vararg{Any,N}) where {N} - @_inline_meta + @inline J = map(i->unalias(A,i), to_indices(A, I)) @boundscheck checkbounds(A, J...) unsafe_view(_maybe_reshape_parent(A, index_ndims(J...)), J...) @@ -211,7 +211,7 @@ function view(r1::AbstractRange, c::Colon) end function unsafe_view(A::AbstractArray, I::Vararg{ViewIndex,N}) where {N} - @_inline_meta + @inline SubArray(A, I) end # When we take the view of a view, it's often possible to "reindex" the parent @@ -221,16 +221,16 @@ end # So we use _maybe_reindex to figure out if there are any arrays of # `CartesianIndex`, and if so, we punt and keep two layers of indirection. unsafe_view(V::SubArray, I::Vararg{ViewIndex,N}) where {N} = - (@_inline_meta; _maybe_reindex(V, I)) -_maybe_reindex(V, I) = (@_inline_meta; _maybe_reindex(V, I, I)) + (@inline; _maybe_reindex(V, I)) +_maybe_reindex(V, I) = (@inline; _maybe_reindex(V, I, I)) _maybe_reindex(V, I, ::Tuple{AbstractArray{<:AbstractCartesianIndex}, Vararg{Any}}) = - (@_inline_meta; SubArray(V, I)) + (@inline; SubArray(V, I)) # But allow arrays of CartesianIndex{1}; they behave just like arrays of Ints _maybe_reindex(V, I, A::Tuple{AbstractArray{<:AbstractCartesianIndex{1}}, Vararg{Any}}) = - (@_inline_meta; _maybe_reindex(V, I, tail(A))) -_maybe_reindex(V, I, A::Tuple{Any, Vararg{Any}}) = (@_inline_meta; _maybe_reindex(V, I, tail(A))) + (@inline; _maybe_reindex(V, I, tail(A))) +_maybe_reindex(V, I, A::Tuple{Any, Vararg{Any}}) = (@inline; _maybe_reindex(V, I, tail(A))) function _maybe_reindex(V, I, ::Tuple{}) - @_inline_meta + @inline @inbounds idxs = to_indices(V.parent, reindex(V.indices, I)) SubArray(V.parent, idxs) end @@ -277,7 +277,7 @@ end # In general, we simply re-index the parent indices by the provided ones SlowSubArray{T,N,P,I} = SubArray{T,N,P,I,false} function getindex(V::SubArray{T,N}, I::Vararg{Int,N}) where {T,N} - @_inline_meta + @inline @boundscheck checkbounds(V, I...) @inbounds r = V.parent[reindex(V.indices, I)...] r @@ -286,7 +286,7 @@ end # But SubArrays with fast linear indexing pre-compute a stride and offset FastSubArray{T,N,P,I} = SubArray{T,N,P,I,true} function getindex(V::FastSubArray, i::Int) - @_inline_meta + @inline @boundscheck checkbounds(V, i) @inbounds r = V.parent[V.offset1 + V.stride1*i] r @@ -296,7 +296,7 @@ end FastContiguousSubArray{T,N,P,I<:Union{Tuple{Union{Slice, AbstractUnitRange}, Vararg{Any}}, Tuple{Vararg{ScalarIndex}}}} = SubArray{T,N,P,I,true} function getindex(V::FastContiguousSubArray, i::Int) - @_inline_meta + @inline @boundscheck checkbounds(V, i) @inbounds r = V.parent[V.offset1 + i] r @@ -304,13 +304,13 @@ end # For vector views with linear indexing, we disambiguate to favor the stride/offset # computation as that'll generally be faster than (or just as fast as) re-indexing into a range. function getindex(V::FastSubArray{<:Any, 1}, i::Int) - @_inline_meta + @inline @boundscheck checkbounds(V, i) @inbounds r = V.parent[V.offset1 + V.stride1*i] r end function getindex(V::FastContiguousSubArray{<:Any, 1}, i::Int) - @_inline_meta + @inline @boundscheck checkbounds(V, i) @inbounds r = V.parent[V.offset1 + i] r @@ -318,31 +318,31 @@ end # Indexed assignment follows the same pattern as `getindex` above function setindex!(V::SubArray{T,N}, x, I::Vararg{Int,N}) where {T,N} - @_inline_meta + @inline @boundscheck checkbounds(V, I...) @inbounds V.parent[reindex(V.indices, I)...] = x V end function setindex!(V::FastSubArray, x, i::Int) - @_inline_meta + @inline @boundscheck checkbounds(V, i) @inbounds V.parent[V.offset1 + V.stride1*i] = x V end function setindex!(V::FastContiguousSubArray, x, i::Int) - @_inline_meta + @inline @boundscheck checkbounds(V, i) @inbounds V.parent[V.offset1 + i] = x V end function setindex!(V::FastSubArray{<:Any, 1}, x, i::Int) - @_inline_meta + @inline @boundscheck checkbounds(V, i) @inbounds V.parent[V.offset1 + V.stride1*i] = x V end function setindex!(V::FastContiguousSubArray{<:Any, 1}, x, i::Int) - @_inline_meta + @inline @boundscheck checkbounds(V, i) @inbounds V.parent[V.offset1 + i] = x V @@ -364,11 +364,11 @@ substrides(strds, I::Tuple{Any, Vararg{Any}}) = throw(ArgumentError("strides is stride(V::SubArray, d::Integer) = d <= ndims(V) ? strides(V)[d] : strides(V)[end] * size(V)[end] compute_stride1(parent::AbstractArray, I::NTuple{N,Any}) where {N} = - (@_inline_meta; compute_stride1(1, fill_to_length(axes(parent), OneTo(1), Val(N)), I)) + (@inline; compute_stride1(1, fill_to_length(axes(parent), OneTo(1), Val(N)), I)) 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*length(inds[1]), tail(inds), tail(I))) + (@inline; 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]))")) @@ -391,42 +391,42 @@ end # The running sum is `f`; the cumulative stride product is `s`. # If the parent is a vector, then we offset the parent's own indices with parameters of I compute_offset1(parent::AbstractVector, stride1::Integer, I::Tuple{AbstractRange}) = - (@_inline_meta; first(I[1]) - stride1*first(axes1(I[1]))) + (@inline; first(I[1]) - stride1*first(axes1(I[1]))) # If the result is one-dimensional and it's a Colon, then linear # indexing uses the indices along the given dimension. # If the result is one-dimensional and it's a range, then linear # indexing might be offset if the index itself is offset # Otherwise linear indexing always matches the parent. compute_offset1(parent, stride1::Integer, I::Tuple) = - (@_inline_meta; compute_offset1(parent, stride1, find_extended_dims(1, I...), find_extended_inds(I...), I)) + (@inline; compute_offset1(parent, stride1, find_extended_dims(1, I...), find_extended_inds(I...), I)) compute_offset1(parent, stride1::Integer, dims::Tuple{Int}, inds::Tuple{Slice}, I::Tuple) = - (@_inline_meta; compute_linindex(parent, I) - stride1*first(axes(parent, dims[1]))) # index-preserving case + (@inline; compute_linindex(parent, I) - stride1*first(axes(parent, dims[1]))) # index-preserving case compute_offset1(parent, stride1::Integer, dims, inds::Tuple{AbstractRange}, I::Tuple) = - (@_inline_meta; compute_linindex(parent, I) - stride1*first(axes1(inds[1]))) # potentially index-offsetting case + (@inline; compute_linindex(parent, I) - stride1*first(axes1(inds[1]))) # potentially index-offsetting case compute_offset1(parent, stride1::Integer, dims, inds, I::Tuple) = - (@_inline_meta; compute_linindex(parent, I) - stride1) + (@inline; compute_linindex(parent, I) - stride1) function compute_linindex(parent, I::NTuple{N,Any}) where N - @_inline_meta + @inline IP = fill_to_length(axes(parent), OneTo(1), Val(N)) compute_linindex(first(LinearIndices(parent)), 1, IP, I) end function compute_linindex(f, s, IP::Tuple, I::Tuple{ScalarIndex, Vararg{Any}}) - @_inline_meta + @inline Δi = I[1]-first(IP[1]) 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 + @inline Δi = first(I[1])-first(IP[1]) compute_linindex(f + Δi*s, s*length(IP[1]), tail(IP), tail(I)) end compute_linindex(f, s, IP::Tuple, I::Tuple{}) = f -find_extended_dims(dim, ::ScalarIndex, I...) = (@_inline_meta; find_extended_dims(dim + 1, I...)) -find_extended_dims(dim, i1, I...) = (@_inline_meta; (dim, find_extended_dims(dim + 1, I...)...)) +find_extended_dims(dim, ::ScalarIndex, I...) = (@inline; find_extended_dims(dim + 1, I...)) +find_extended_dims(dim, i1, I...) = (@inline; (dim, find_extended_dims(dim + 1, I...)...)) find_extended_dims(dim) = () -find_extended_inds(::ScalarIndex, I...) = (@_inline_meta; find_extended_inds(I...)) -find_extended_inds(i1, I...) = (@_inline_meta; (i1, find_extended_inds(I...)...)) +find_extended_inds(::ScalarIndex, I...) = (@inline; find_extended_inds(I...)) +find_extended_inds(i1, I...) = (@inline; (i1, find_extended_inds(I...)...)) find_extended_inds() = () function unsafe_convert(::Type{Ptr{T}}, V::SubArray{T,N,P,<:Tuple{Vararg{RangeIndex}}}) where {T,N,P} @@ -448,10 +448,10 @@ end # indices are taken from the range/vector # Since bounds-checking is performance-critical and uses # indices, it's worth optimizing these implementations thoroughly -axes(S::SubArray) = (@_inline_meta; _indices_sub(S.indices...)) -_indices_sub(::Real, I...) = (@_inline_meta; _indices_sub(I...)) +axes(S::SubArray) = (@inline; _indices_sub(S.indices...)) +_indices_sub(::Real, I...) = (@inline; _indices_sub(I...)) _indices_sub() = () function _indices_sub(i1::AbstractArray, I...) - @_inline_meta + @inline (axes(i1)..., _indices_sub(I...)...) end diff --git a/base/tuple.jl b/base/tuple.jl index ead8bc9919a869..2e1db9a316bfd4 100644 --- a/base/tuple.jl +++ b/base/tuple.jl @@ -51,12 +51,12 @@ true """ function setindex(x::Tuple, v, i::Integer) @boundscheck 1 <= i <= length(x) || throw(BoundsError(x, i)) - @_inline_meta + @inline _setindex(v, i, x...) end function _setindex(v, i::Integer, args...) - @_inline_meta + @inline return ntuple(j -> ifelse(j == i, v, args[j]), length(args)) end @@ -64,7 +64,7 @@ end ## iterating ## function iterate(@nospecialize(t::Tuple), i::Int=1) - @_inline_meta + @inline return (1 <= i <= length(t)) ? (@inbounds t[i], i + 1) : nothing end @@ -74,19 +74,19 @@ prevind(@nospecialize(t::Tuple), i::Integer) = Int(i)-1 nextind(@nospecialize(t::Tuple), i::Integer) = Int(i)+1 function keys(t::Tuple, t2::Tuple...) - @_inline_meta + @inline OneTo(_maxlength(t, t2...)) end _maxlength(t::Tuple) = length(t) function _maxlength(t::Tuple, t2::Tuple, t3::Tuple...) - @_inline_meta + @inline max(length(t), _maxlength(t2, t3...)) end # this allows partial evaluation of bounded sequences of next() calls on tuples, # while reducing to plain next() for arbitrary iterables. -indexed_iterate(t::Tuple, i::Int, state=1) = (@_inline_meta; (getfield(t, i), i+1)) -indexed_iterate(a::Array, i::Int, state=1) = (@_inline_meta; (a[i], i+1)) +indexed_iterate(t::Tuple, i::Int, state=1) = (@inline; (getfield(t, i), i+1)) +indexed_iterate(a::Array, i::Int, state=1) = (@inline; (a[i], i+1)) function indexed_iterate(I, i) x = iterate(I) x === nothing && throw(BoundsError(I, i)) @@ -203,13 +203,13 @@ ERROR: ArgumentError: Cannot call front on an empty tuple. ``` """ function front(t::Tuple) - @_inline_meta + @inline _front(t...) end _front() = throw(ArgumentError("Cannot call front on an empty tuple.")) _front(v) = () function _front(v, t...) - @_inline_meta + @inline (v, _front(t...)...) end @@ -217,10 +217,10 @@ end # 1 argument function map(f, t::Tuple{}) = () -map(f, t::Tuple{Any,}) = (@_inline_meta; (f(t[1]),)) -map(f, t::Tuple{Any, Any}) = (@_inline_meta; (f(t[1]), f(t[2]))) -map(f, t::Tuple{Any, Any, Any}) = (@_inline_meta; (f(t[1]), f(t[2]), f(t[3]))) -map(f, t::Tuple) = (@_inline_meta; (f(t[1]), map(f,tail(t))...)) +map(f, t::Tuple{Any,}) = (@inline; (f(t[1]),)) +map(f, t::Tuple{Any, Any}) = (@inline; (f(t[1]), f(t[2]))) +map(f, t::Tuple{Any, Any, Any}) = (@inline; (f(t[1]), f(t[2]), f(t[3]))) +map(f, t::Tuple) = (@inline; (f(t[1]), map(f,tail(t))...)) # stop inlining after some number of arguments to avoid code blowup const Any32{N} = Tuple{Any,Any,Any,Any,Any,Any,Any,Any, Any,Any,Any,Any,Any,Any,Any,Any, @@ -242,10 +242,10 @@ function map(f, t::Any32) end # 2 argument function map(f, t::Tuple{}, s::Tuple{}) = () -map(f, t::Tuple{Any,}, s::Tuple{Any,}) = (@_inline_meta; (f(t[1],s[1]),)) -map(f, t::Tuple{Any,Any}, s::Tuple{Any,Any}) = (@_inline_meta; (f(t[1],s[1]), f(t[2],s[2]))) +map(f, t::Tuple{Any,}, s::Tuple{Any,}) = (@inline; (f(t[1],s[1]),)) +map(f, t::Tuple{Any,Any}, s::Tuple{Any,Any}) = (@inline; (f(t[1],s[1]), f(t[2],s[2]))) function map(f, t::Tuple, s::Tuple) - @_inline_meta + @inline (f(t[1],s[1]), map(f, tail(t), tail(s))...) end function map(f, t::Any32, s::Any32) @@ -261,7 +261,7 @@ heads(ts::Tuple...) = map(t -> t[1], ts) tails(ts::Tuple...) = map(tail, ts) map(f, ::Tuple{}...) = () function map(f, t1::Tuple, t2::Tuple, ts::Tuple...) - @_inline_meta + @inline (f(heads(t1, t2, ts...)...), map(f, tails(t1, t2, ts...)...)...) end function map(f, t1::Any32, t2::Any32, ts::Any32...) @@ -281,7 +281,7 @@ fill_to_length(t::Tuple{}, val, ::Val{1}) = (val,) fill_to_length(t::Tuple{Any}, val, ::Val{2}) = (t..., val) fill_to_length(t::Tuple{}, val, ::Val{2}) = (val, val) #function fill_to_length(t::Tuple, val, ::Val{N}) where {N} -# @_inline_meta +# @inline # return (t..., ntuple(i -> val, N - length(t))...) #end @@ -318,12 +318,12 @@ Tuple(x::Array{T,0}) where {T} = tuple(getindex(x)) _totuple(::Type{Tuple{}}, itr, s...) = () function _totuple_err(@nospecialize T) - @_noinline_meta + @noinline throw(ArgumentError("too few elements for tuple type $T")) end function _totuple(::Type{T}, itr, s::Vararg{Any,N}) where {T,N} - @_inline_meta + @inline y = iterate(itr, s...) y === nothing && _totuple_err(T) t1 = convert(fieldtype(T, 1), y[1]) @@ -514,7 +514,7 @@ any(x::Tuple{Bool, Bool, Bool}) = x[1]|x[2]|x[3] # equivalent to any(f, t), to be used only in bootstrap _tuple_any(f::Function, t::Tuple) = _tuple_any(f, false, t...) function _tuple_any(f::Function, tf::Bool, a, b...) - @_inline_meta + @inline _tuple_any(f, tf | f(a), b...) end _tuple_any(f::Function, tf::Bool) = tf diff --git a/base/twiceprecision.jl b/base/twiceprecision.jl index a7ff116b56b360..7f338ce98a1f5d 100644 --- a/base/twiceprecision.jl +++ b/base/twiceprecision.jl @@ -463,7 +463,7 @@ end # This assumes that r.step has already been split so that (0:len-1)*r.step.hi is exact function unsafe_getindex(r::StepRangeLen{T,<:TwicePrecision,<:TwicePrecision}, i::Integer) where T # Very similar to _getindex_hiprec, but optimized to avoid a 2nd call to add12 - @_inline_meta + @inline i isa Bool && throw(ArgumentError("invalid index: $i of type Bool")) u = i - r.offset shift_hi, shift_lo = u*r.step.hi, u*r.step.lo @@ -766,7 +766,7 @@ narrow(::Type{Float32}) = Float16 narrow(::Type{Float16}) = Float16 function _tp_prod(t::TwicePrecision, x, y...) - @_inline_meta + @inline _tp_prod(t * x, y...) end _tp_prod(t::TwicePrecision) = t diff --git a/stdlib/LinearAlgebra/src/adjtrans.jl b/stdlib/LinearAlgebra/src/adjtrans.jl index 29f91e6edaed49..f5903f380ee533 100644 --- a/stdlib/LinearAlgebra/src/adjtrans.jl +++ b/stdlib/LinearAlgebra/src/adjtrans.jl @@ -1,6 +1,6 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -using Base: @propagate_inbounds, @_inline_meta +using Base: @propagate_inbounds import Base: length, size, axes, IndexStyle, getindex, setindex!, parent, vec, convert, similar ### basic definitions (types, aliases, constructors, abstractarray interface, sundry similar) diff --git a/test/compiler/codegen.jl b/test/compiler/codegen.jl index cc6095b867d419..f0b1623a443d15 100644 --- a/test/compiler/codegen.jl +++ b/test/compiler/codegen.jl @@ -350,7 +350,7 @@ struct Const{T<:Array} end @eval Base.getindex(A::Const, i1::Int) = Core.const_arrayref($(Expr(:boundscheck)), A.a, i1) -@eval Base.getindex(A::Const, i1::Int, i2::Int, I::Int...) = (Base.@_inline_meta; Core.const_arrayref($(Expr(:boundscheck)), A.a, i1, i2, I...)) +@eval Base.getindex(A::Const, i1::Int, i2::Int, I::Int...) = (@inline; Core.const_arrayref($(Expr(:boundscheck)), A.a, i1, i2, I...)) function foo31018!(a, b) @aliasscope for i in eachindex(a, b) diff --git a/test/opaque_closure.jl b/test/opaque_closure.jl index 796aac7072c605..11e4929c36edda 100644 --- a/test/opaque_closure.jl +++ b/test/opaque_closure.jl @@ -192,7 +192,7 @@ end # OpaqueClosure ABI f_oc_noinline(x) = @opaque function (y) - @Base._noinline_meta + @noinline x + y end diff --git a/test/syntax.jl b/test/syntax.jl index 9b31c0b874fbdf..09a91a31305f31 100644 --- a/test/syntax.jl +++ b/test/syntax.jl @@ -1510,7 +1510,7 @@ let ex = Meta.parse("@test27521(2) do y; y; end") end # issue #27129 -f27129(x = 1) = (@Base._inline_meta; x) +f27129(x = 1) = (@inline; x) for meth in methods(f27129) @test ccall(:jl_uncompress_ir, Any, (Any, Ptr{Cvoid}, Any), meth, C_NULL, meth.source).inlineable end diff --git a/test/vecelement.jl b/test/vecelement.jl index 5652ea10d3aa6a..6638f06f4f3582 100644 --- a/test/vecelement.jl +++ b/test/vecelement.jl @@ -96,7 +96,7 @@ const _llvmtypes = Dict{DataType, String}( ret <$(N) x $(llvmT)> %3 """ return quote - Base.@_inline_meta + Base.@inline Core.getfield(Base, :llvmcall)($exp, Vec{$N, $T}, Tuple{Vec{$N, $T}, Vec{$N, $T}}, x, y) end end From 848d2734e8d068ce9d0d5b715e618de13798fd40 Mon Sep 17 00:00:00 2001 From: Dilum Aluthge Date: Wed, 25 Aug 2021 05:48:06 -0400 Subject: [PATCH 118/135] Remove some trailing whitespace (#41998) --- stdlib/REPL/src/docview.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/REPL/src/docview.jl b/stdlib/REPL/src/docview.jl index c4b43399a89c0e..000c1372cbe6a9 100644 --- a/stdlib/REPL/src/docview.jl +++ b/stdlib/REPL/src/docview.jl @@ -405,7 +405,7 @@ end function repl_latex(io::IO, s0::String) # This has rampant `Core.Box` problems (#15276). Use the tricks of # https://docs.julialang.org/en/v1/manual/performance-tips/#man-performance-captured - # We're changing some of the values so the `let` trick isn't applicable. + # We're changing some of the values so the `let` trick isn't applicable. s::String = s0 latex::String = symbol_latex(s) if isempty(latex) From cc4be25c4220e9a1d2752e0fcd99c01deb400999 Mon Sep 17 00:00:00 2001 From: DilumAluthgeBot <43731525+DilumAluthgeBot@users.noreply.github.com> Date: Wed, 25 Aug 2021 12:41:21 +0000 Subject: [PATCH 119/135] =?UTF-8?q?=F0=9F=A4=96=20Bump=20the=20Pkg=20stdli?= =?UTF-8?q?b=20from=205434d05f=20to=207a35bbe9=20(#41979)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Dilum Aluthge --- .../Pkg-5434d05fba65f4ad735a85644af3c9fa16a1d75c.tar.gz/md5 | 1 - .../Pkg-5434d05fba65f4ad735a85644af3c9fa16a1d75c.tar.gz/sha512 | 1 - .../Pkg-7a35bbe98197d49c867f93cc421f1ebea869d814.tar.gz/md5 | 1 + .../Pkg-7a35bbe98197d49c867f93cc421f1ebea869d814.tar.gz/sha512 | 1 + stdlib/Pkg.version | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 deps/checksums/Pkg-5434d05fba65f4ad735a85644af3c9fa16a1d75c.tar.gz/md5 delete mode 100644 deps/checksums/Pkg-5434d05fba65f4ad735a85644af3c9fa16a1d75c.tar.gz/sha512 create mode 100644 deps/checksums/Pkg-7a35bbe98197d49c867f93cc421f1ebea869d814.tar.gz/md5 create mode 100644 deps/checksums/Pkg-7a35bbe98197d49c867f93cc421f1ebea869d814.tar.gz/sha512 diff --git a/deps/checksums/Pkg-5434d05fba65f4ad735a85644af3c9fa16a1d75c.tar.gz/md5 b/deps/checksums/Pkg-5434d05fba65f4ad735a85644af3c9fa16a1d75c.tar.gz/md5 deleted file mode 100644 index fe00ce3a5adaa6..00000000000000 --- a/deps/checksums/Pkg-5434d05fba65f4ad735a85644af3c9fa16a1d75c.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -76a298ceebe05a10d5f9740fc1648d6e diff --git a/deps/checksums/Pkg-5434d05fba65f4ad735a85644af3c9fa16a1d75c.tar.gz/sha512 b/deps/checksums/Pkg-5434d05fba65f4ad735a85644af3c9fa16a1d75c.tar.gz/sha512 deleted file mode 100644 index c35c85dd7d4601..00000000000000 --- a/deps/checksums/Pkg-5434d05fba65f4ad735a85644af3c9fa16a1d75c.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -6e5abec3dc08b39939b94ca8bd1e35e89e3254058cd0cdadc6e7ba4e872784dee363aa5fbf57d1981d4d2f49fea19bfe5a0f774ec869a96b36176e2bb3ab1b93 diff --git a/deps/checksums/Pkg-7a35bbe98197d49c867f93cc421f1ebea869d814.tar.gz/md5 b/deps/checksums/Pkg-7a35bbe98197d49c867f93cc421f1ebea869d814.tar.gz/md5 new file mode 100644 index 00000000000000..fcb74a5901050c --- /dev/null +++ b/deps/checksums/Pkg-7a35bbe98197d49c867f93cc421f1ebea869d814.tar.gz/md5 @@ -0,0 +1 @@ +b33e568437318ecd8a45f1cd0d3f68fe diff --git a/deps/checksums/Pkg-7a35bbe98197d49c867f93cc421f1ebea869d814.tar.gz/sha512 b/deps/checksums/Pkg-7a35bbe98197d49c867f93cc421f1ebea869d814.tar.gz/sha512 new file mode 100644 index 00000000000000..b8b84033085270 --- /dev/null +++ b/deps/checksums/Pkg-7a35bbe98197d49c867f93cc421f1ebea869d814.tar.gz/sha512 @@ -0,0 +1 @@ +c66768fabe0a999564d6760289f1b457265c4c42ecda34917a314b7093100f7bd3e6bf0f7d4893e1a5acc21182a8b20afc6e765c14a5175960a47e30b0809b28 diff --git a/stdlib/Pkg.version b/stdlib/Pkg.version index 2b7ec72564ddcc..3357cc846271f2 100644 --- a/stdlib/Pkg.version +++ b/stdlib/Pkg.version @@ -1,2 +1,2 @@ PKG_BRANCH = master -PKG_SHA1 = 5434d05fba65f4ad735a85644af3c9fa16a1d75c +PKG_SHA1 = 7a35bbe98197d49c867f93cc421f1ebea869d814 From a2ec425beff559e6599ac63ea3b0be434a8e4939 Mon Sep 17 00:00:00 2001 From: Sebastian Stock <42280794+sostock@users.noreply.github.com> Date: Wed, 25 Aug 2021 16:31:56 +0200 Subject: [PATCH 120/135] Fix bug introduced in #41513 (#41970) --- stdlib/LinearAlgebra/src/blas.jl | 2 +- stdlib/LinearAlgebra/test/blas.jl | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/stdlib/LinearAlgebra/src/blas.jl b/stdlib/LinearAlgebra/src/blas.jl index 3092e87095b445..661e9e2b156177 100644 --- a/stdlib/LinearAlgebra/src/blas.jl +++ b/stdlib/LinearAlgebra/src/blas.jl @@ -669,7 +669,7 @@ for (fname, elty) in ((:dgemv_,:Float64), sX = stride(X,1) pX = pointer(X, sX > 0 ? firstindex(X) : lastindex(X)) sY = stride(Y,1) - pY = pointer(Y, sY > 0 ? firstindex(X) : lastindex(X)) + pY = pointer(Y, sY > 0 ? firstindex(Y) : lastindex(Y)) GC.@preserve X Y ccall((@blasfunc($fname), libblastrampoline), Cvoid, (Ref{UInt8}, Ref{BlasInt}, Ref{BlasInt}, Ref{$elty}, Ptr{$elty}, Ref{BlasInt}, Ptr{$elty}, Ref{BlasInt}, diff --git a/stdlib/LinearAlgebra/test/blas.jl b/stdlib/LinearAlgebra/test/blas.jl index f317c8ee12538f..df29c171b20606 100644 --- a/stdlib/LinearAlgebra/test/blas.jl +++ b/stdlib/LinearAlgebra/test/blas.jl @@ -373,29 +373,29 @@ Random.seed!(100) @testset "non-standard strides" begin if elty <: Complex A = elty[1+2im 3+4im 5+6im 7+8im; 2+3im 4+5im 6+7im 8+9im; 3+4im 5+6im 7+8im 9+10im] - v = elty[1+2im, 2+3im, 3+4im, 4+5im] - dest = view(ones(elty, 5), 4:-2:2) - @test BLAS.gemv!('N', elty(2), view(A, 2:3, 2:2:4), view(v, 1:3:4), elty(3), dest) == elty[-35+178im, -39+202im] + v = elty[1+2im, 2+3im, 3+4im, 4+5im, 5+6im] + dest = view(ones(elty, 7), 6:-2:2) + @test BLAS.gemv!('N', elty(2), view(A, :, 2:2:4), view(v, 1:3:4), elty(3), dest) == elty[-31+154im, -35+178im, -39+202im] @test BLAS.gemv('N', elty(-1), view(A, 2:3, 2:3), view(v, 2:-1:1)) == elty[15-41im, 17-49im] @test BLAS.gemv('N', view(A, 1:0, 1:2), view(v, 1:2)) == elty[] dest = view(ones(elty, 5), 4:-2:2) - @test BLAS.gemv!('T', elty(2), view(A, 2:3, 2:2:4), view(v, 1:3:4), elty(3), dest) == elty[-29+124im, -45+220im] + @test BLAS.gemv!('T', elty(2), view(A, :, 2:2:4), view(v, 1:2:5), elty(3), dest) == elty[-45+202im, -69+370im] @test BLAS.gemv('T', elty(-1), view(A, 2:3, 2:3), view(v, 2:-1:1)) == elty[14-38im, 18-54im] @test BLAS.gemv('T', view(A, 2:3, 2:1), view(v, 1:2)) == elty[] dest = view(ones(elty, 5), 4:-2:2) - @test BLAS.gemv!('C', elty(2), view(A, 2:3, 2:2:4), view(v, 1:3:4), elty(3), dest) == elty[131+8im, 227+24im] + @test BLAS.gemv!('C', elty(2), view(A, :, 2:2:4), view(v, 5:-2:1), elty(3), dest) == elty[179+6im, 347+30im] @test BLAS.gemv('C', elty(-1), view(A, 2:3, 2:3), view(v, 2:-1:1)) == elty[-40-6im, -56-10im] @test BLAS.gemv('C', view(A, 2:3, 2:1), view(v, 1:2)) == elty[] else A = elty[1 2 3 4; 5 6 7 8; 9 10 11 12] - v = elty[1, 2, 3, 4] - dest = view(ones(elty, 5), 4:-2:2) - @test BLAS.gemv!('N', elty(2), view(A, 2:3, 2:2:4), view(v, 1:3:4), elty(3), dest) == elty[79, 119] + v = elty[1, 2, 3, 4, 5] + dest = view(ones(elty, 7), 6:-2:2) + @test BLAS.gemv!('N', elty(2), view(A, :, 2:2:4), view(v, 1:3:4), elty(3), dest) == elty[39, 79, 119] @test BLAS.gemv('N', elty(-1), view(A, 2:3, 2:3), view(v, 2:-1:1)) == elty[-19, -31] @test BLAS.gemv('N', view(A, 1:0, 1:2), view(v, 1:2)) == elty[] for trans = ('T', 'C') dest = view(ones(elty, 5), 4:-2:2) - @test BLAS.gemv!(trans, elty(2), view(A, 2:3, 2:2:4), view(v, 1:3:4), elty(3), dest) == elty[95, 115] + @test BLAS.gemv!(trans, elty(2), view(A, :, 2:2:4), view(v, 1:2:5), elty(3), dest) == elty[143, 179] @test BLAS.gemv(trans, elty(-1), view(A, 2:3, 2:3), view(v, 2:-1:1)) == elty[-22, -25] @test BLAS.gemv(trans, view(A, 2:3, 2:1), view(v, 1:2)) == elty[] end From 6b5bc3b91183ce1faa222444c910afec3ad6dc3d Mon Sep 17 00:00:00 2001 From: Alex Arslan Date: Wed, 25 Aug 2021 08:07:23 -0700 Subject: [PATCH 121/135] Update LLVM libunwind to 12.0.1 (#41993) --- deps/Versions.make | 2 +- deps/checksums/llvmunwind | 38 +++++++++++++++++++++++++-- stdlib/LLVMLibUnwind_jll/Project.toml | 2 +- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/deps/Versions.make b/deps/Versions.make index fb23858d455557..43c9f4b3e01c31 100644 --- a/deps/Versions.make +++ b/deps/Versions.make @@ -54,7 +54,7 @@ LLVM_TOOLS_JLL_VER := 12.0.1+0 LLVM_TOOLS_ASSERT_JLL_VER := 12.0.1+0 # LLVM libunwind -LLVMUNWIND_VER := 11.0.1 +LLVMUNWIND_VER := 12.0.1 LLVMUNWIND_JLL_NAME := LLVMLibUnwind # MbedTLS diff --git a/deps/checksums/llvmunwind b/deps/checksums/llvmunwind index c2876364d4066a..fd15b697754ded 100644 --- a/deps/checksums/llvmunwind +++ b/deps/checksums/llvmunwind @@ -1,2 +1,36 @@ -llvmunwind-11.0.1.tar.xz/md5/b030a6d5807d797e505e4fbd32a36c2a -llvmunwind-11.0.1.tar.xz/sha512/9cfa1eae720a99ac10d05aa4d1e1b205da5c78841aafd6022a87d1272c821a43402309dfa42d8863bc6dea330ab2c0917d62284b572abb56641aa80e56a9be69 +llvmunwind-12.0.1.tar.xz/md5/4ec327cee517fdb1f6a20e83748e2c7b +llvmunwind-12.0.1.tar.xz/sha512/847b6ba03010a43f4fdbfdc49bf16d18fd18474d01584712e651b11191814bf7c1cf53475021d9ee447ed78413202b4ed97973d7bdd851d3e49f8d06f55a7af4 +LLVMLibUnwind.v12.0.1+0.aarch64-apple-darwin.tar.gz/md5/b95ad4844e649bf46db43683b55b9f4f +LLVMLibUnwind.v12.0.1+0.aarch64-apple-darwin.tar.gz/sha256/ +LLVMLibUnwind.v12.0.1+0.aarch64-apple-darwin.tar.gz/md5/b95ad4844e649bf46db43683b55b9f4f +LLVMLibUnwind.v12.0.1+0.aarch64-apple-darwin.tar.gz/sha512/15e0996aebe6db91fe58121001aa7ea4b23685ead3c26b5d89afae34b535e34b4e801a971f4854d8e1a1fbc805cece06272470622eef863e225358113a127913 +LLVMLibUnwind.v12.0.1+0.aarch64-linux-gnu.tar.gz/md5/6d8783dc9b86c9884e0877f0d8ac4167 +LLVMLibUnwind.v12.0.1+0.aarch64-linux-gnu.tar.gz/sha512/d3b0c81498220d77e4f3cc684fb2cc0653792c381207390e695ac30bc74249f96a333a406b2cebdaca14e0b0a27b188cba6209bb5c1cbbb5c184d5626dbdc7a0 +LLVMLibUnwind.v12.0.1+0.aarch64-linux-musl.tar.gz/md5/052a35e879d52244e4b0804be875a38f +LLVMLibUnwind.v12.0.1+0.aarch64-linux-musl.tar.gz/sha512/d1b34fb97f9928e046d3131a050454710a93d38e60287b7e3c92f179f436586d3230cf90b0ca0eb8a3f9ef89fef7b1ffd7d52871645dfa233a8b07ca87ea2ee4 +LLVMLibUnwind.v12.0.1+0.armv6l-linux-gnueabihf.tar.gz/md5/1ad96a03a5dde506b5c05773b1849ec4 +LLVMLibUnwind.v12.0.1+0.armv6l-linux-gnueabihf.tar.gz/sha512/82306fb7b920fa7c71bd53b23d6915e7f256e8da9679cc926a53bb0d879f1f4469f43efe556ca32c9ef59e27b435572c7b39859090652635db4eeefdec0d1685 +LLVMLibUnwind.v12.0.1+0.armv6l-linux-musleabihf.tar.gz/md5/6a24fcd3a4dc3b1a98bb7963b1bb4930 +LLVMLibUnwind.v12.0.1+0.armv6l-linux-musleabihf.tar.gz/sha512/9ba6b83ccec061a1e5260c807dc8afd6e18799431b25a7e65b97662cc4db02509d02ea07fe12025d80914cec7383624b1c8fc9add46511c668e184ede263ac52 +LLVMLibUnwind.v12.0.1+0.armv7l-linux-gnueabihf.tar.gz/md5/09f1bfcf58a4124561553ab5005f9538 +LLVMLibUnwind.v12.0.1+0.armv7l-linux-gnueabihf.tar.gz/sha512/b0907cb857131183ffc338780c6c6dd1d48bf0ba61c3da1b8f20cf9a943373173b621cf9b2e8f1fbc657059a896b84aa025e6d4f0f1d1e8b623fac3e96541765 +LLVMLibUnwind.v12.0.1+0.armv7l-linux-musleabihf.tar.gz/md5/19158bcfae716b26f924d67c4e719342 +LLVMLibUnwind.v12.0.1+0.armv7l-linux-musleabihf.tar.gz/sha512/a90be57990b6699cb737ba96904e94e1f082601ca9d01e670f025b5500f526980741921c9cf672accab78cb5327714ab6ecdbb875174088f0773ebb627a98819 +LLVMLibUnwind.v12.0.1+0.i686-linux-gnu.tar.gz/md5/ba75556eb96b2bcdaf73ff68386d3bc3 +LLVMLibUnwind.v12.0.1+0.i686-linux-gnu.tar.gz/sha512/612fb765695b7aae11ef29608eedf8b959f60c021287a67b03a2a0f57a5814001ffa9b261c9d60d5f3d0582c06c2b41f75fd3afb66a045a248bd43d29e304c97 +LLVMLibUnwind.v12.0.1+0.i686-linux-musl.tar.gz/md5/2fcbceeb1bfde29be0cbca8bb6718bfe +LLVMLibUnwind.v12.0.1+0.i686-linux-musl.tar.gz/sha512/58f281cfc70b3f8a59cf4faa7732824637c811ddc5ea6a058f294f4c3ed4fa6c8ddab5c007567b439f2854635cf4fd146284059bfbc73e7006000ced9383f705 +LLVMLibUnwind.v12.0.1+0.i686-w64-mingw32.tar.gz/md5/153c028d97dceb6924414a7a9a137e1e +LLVMLibUnwind.v12.0.1+0.i686-w64-mingw32.tar.gz/sha512/7ae1f197600eabde9036ae58623de34a6d25636d7861777e324eb97902f65e26c6f3775e757178f8914b0cb6c2e925413f5ffc6abc9b6138470dc9e67a17f212 +LLVMLibUnwind.v12.0.1+0.powerpc64le-linux-gnu.tar.gz/md5/c08a6cf3e1baf156eb05003ed4e9ebe9 +LLVMLibUnwind.v12.0.1+0.powerpc64le-linux-gnu.tar.gz/sha512/f74e44986622329990842cb3ff549ff9254c81863d8bee468b0e58b7621067e7e7f7f18e4cbeafad6a05e0c107323de6828a78dc7afbcd7cd1892383ff417968 +LLVMLibUnwind.v12.0.1+0.x86_64-apple-darwin.tar.gz/md5/caf151150e56827be09acca6964d2b18 +LLVMLibUnwind.v12.0.1+0.x86_64-apple-darwin.tar.gz/sha512/cb3e7aa71367ec4a115bccc2e8ac6bd5d9f22b3935b3889eee1fbf7303c5f553d7d3108977bc1f6c9b6917a6ed9e10bff211fd56b8169233ceae287b112894c2 +LLVMLibUnwind.v12.0.1+0.x86_64-linux-gnu.tar.gz/md5/d95874cbf6f8b55bc314c3968a6a4563 +LLVMLibUnwind.v12.0.1+0.x86_64-linux-gnu.tar.gz/sha512/4986a8d9cc9d8761a99a4f02d017b424484233d4cbe2d4f49ccd371591384b1b8d1c4d31cb908505b86b00f2b164568e57751dd949d91af203ee4a582971798a +LLVMLibUnwind.v12.0.1+0.x86_64-linux-musl.tar.gz/md5/89077d871e15425b1f4c2451fb19a1b2 +LLVMLibUnwind.v12.0.1+0.x86_64-linux-musl.tar.gz/sha512/b65a218b05ade2e2d1582188897b036a4596d09cf65558f178c49c1a1a62b7d992b1d99fbe86a027dc83b614f178e6061f3dfb695b18a8e2b6bf76779b741d96 +LLVMLibUnwind.v12.0.1+0.x86_64-unknown-freebsd.tar.gz/md5/54ac594b4c8e7f261034a8829dad5e34 +LLVMLibUnwind.v12.0.1+0.x86_64-unknown-freebsd.tar.gz/sha512/a43756afd92081e6dd7244d162862fc318b41ca110a5e8be6e4ee2d8fdfd8fb0f79961ae55e48913e055779791bd1c0ecd34fd59281fb66b3c4f24a1f44128f0 +LLVMLibUnwind.v12.0.1+0.x86_64-w64-mingw32.tar.gz/md5/83cf8fc2a085a73b8af4245a82b7d32f +LLVMLibUnwind.v12.0.1+0.x86_64-w64-mingw32.tar.gz/sha512/297a5c7b33bd3f57878871eccb3b9879ea5549639523a1b9db356b710cafb232906a74d668315340d60ba0c5087d3400f14ab92c3704e32e062e6b546abf7df6 diff --git a/stdlib/LLVMLibUnwind_jll/Project.toml b/stdlib/LLVMLibUnwind_jll/Project.toml index a0791406671843..36c24111d4d311 100644 --- a/stdlib/LLVMLibUnwind_jll/Project.toml +++ b/stdlib/LLVMLibUnwind_jll/Project.toml @@ -1,6 +1,6 @@ name = "LLVMLibUnwind_jll" uuid = "47c5dbc3-30ba-59ef-96a6-123e260183d9" -version = "11.0.1+1" +version = "12.0.1+0" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" From a11de31665d46b63fe1ff043d056c3c5483afdc6 Mon Sep 17 00:00:00 2001 From: Simeon Schaub Date: Wed, 25 Aug 2021 18:19:27 +0200 Subject: [PATCH 122/135] debuginfo: store location of loop boundary (#41857) Since lowering always inserts gotos and other instructions after loop bodies, this allows debuggers to give a more useful location for these instructions. fixes JuliaDebug/JuliaInterpreter.jl#485 --- src/julia-parser.scm | 4 ++-- stdlib/Distributed/src/macros.jl | 3 +++ test/testhelpers/coverage_file.info | 3 ++- test/testhelpers/coverage_file.info.bad | 7 ++++--- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/julia-parser.scm b/src/julia-parser.scm index a22e7141358226..dac32bdf81066e 100644 --- a/src/julia-parser.scm +++ b/src/julia-parser.scm @@ -1376,14 +1376,14 @@ (if (eq? word 'quote) (list 'quote blk) blk)))) - ((while) (begin0 (list 'while (parse-cond s) (parse-block s)) + ((while) (begin0 (list 'while (parse-cond s) (append (parse-block s) (list (line-number-node s)))) (expect-end s word))) ((for) (let* ((ranges (parse-comma-separated-iters s)) (body (parse-block s))) (expect-end s word) `(for ,(if (length= ranges 1) (car ranges) (cons 'block ranges)) - ,body))) + ,(append body (list (line-number-node s)))))) ((let) (let ((binds (if (memv (peek-token s) '(#\newline #\;)) diff --git a/stdlib/Distributed/src/macros.jl b/stdlib/Distributed/src/macros.jl index 6603d627c34092..f96338b69e9fb4 100644 --- a/stdlib/Distributed/src/macros.jl +++ b/stdlib/Distributed/src/macros.jl @@ -347,6 +347,9 @@ macro distributed(args...) var = loop.args[1].args[1] r = loop.args[1].args[2] body = loop.args[2] + if Meta.isexpr(body, :block) && body.args[end] isa LineNumberNode + resize!(body.args, length(body.args) - 1) + end if na==1 syncvar = esc(Base.sync_varname) return quote diff --git a/test/testhelpers/coverage_file.info b/test/testhelpers/coverage_file.info index 9b4b1c1f2f96e7..1dea941fb2441d 100644 --- a/test/testhelpers/coverage_file.info +++ b/test/testhelpers/coverage_file.info @@ -4,7 +4,8 @@ DA:4,1 DA:5,0 DA:7,1 DA:8,1 -DA:9,5 +DA:9,3 +DA:10,5 DA:11,1 DA:12,1 DA:14,0 diff --git a/test/testhelpers/coverage_file.info.bad b/test/testhelpers/coverage_file.info.bad index 44e33a9df68c79..d4d81eda267873 100644 --- a/test/testhelpers/coverage_file.info.bad +++ b/test/testhelpers/coverage_file.info.bad @@ -4,7 +4,8 @@ DA:4,1 DA:5,0 DA:7,1 DA:8,1 -DA:9,5 +DA:9,3 +DA:10,5 DA:11,1 DA:12,1 DA:14,0 @@ -14,6 +15,6 @@ DA:19,1 DA:20,1 DA:22,1 DA:1234,0 -LH:11 -LF:15 +LH:12 +LF:16 end_of_record From 13bcdf124f7b8baa7fca517ec015ec4b6eb34faa Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Thu, 5 Aug 2021 18:03:39 -0400 Subject: [PATCH 123/135] simplify and improve type intersection algorithm a bit This removes some code and makes a class of results more conservative, fixing some potential cases of unsoundness. --- src/subtype.c | 128 +++++++++++++++++------------------------------- test/subtype.jl | 60 +++++++++++++++++------ 2 files changed, 92 insertions(+), 96 deletions(-) diff --git a/src/subtype.c b/src/subtype.c index 152d17daeaaaae..0a20b0db09b558 100644 --- a/src/subtype.c +++ b/src/subtype.c @@ -68,15 +68,14 @@ typedef struct jl_varbinding_t { int8_t occurs_inv; // occurs in invariant position int8_t occurs_cov; // # of occurrences in covariant position int8_t concrete; // 1 if another variable has a constraint forcing this one to be concrete - // in covariant position, we need to try constraining a variable in different ways: - // 0 - unconstrained - // 1 - less than - // 2 - greater than - // 3 - inexpressible - occurs when the var has non-trivial overlap with another type, - // and we would need to return `intersect(var,other)`. in this case - // we choose to over-estimate the intersection by returning the var. + // constraintkind: in covariant position, we try three different ways to compute var ∩ type: + // let ub = var.ub ∩ type + // 0 - var.ub <: type ? var : ub + // 1 - var.ub = ub; return var + // 2 - either (var.ub = ub; return var), or return ub int8_t constraintkind; int8_t intvalued; // must be integer-valued; i.e. occurs as N in Vararg{_,N} + int8_t limited; int16_t depth0; // # of invariant constructors nested around the UnionAll type for this var // when this variable's integer value is compared to that of another, // it equals `other + offset`. used by vararg length parameters. @@ -759,7 +758,7 @@ static jl_unionall_t *unalias_unionall(jl_unionall_t *u, jl_stenv_t *e) static int subtype_unionall(jl_value_t *t, jl_unionall_t *u, jl_stenv_t *e, int8_t R, int param) { u = unalias_unionall(u, e); - jl_varbinding_t vb = { u->var, u->var->lb, u->var->ub, R, 0, 0, 0, 0, 0, + jl_varbinding_t vb = { u->var, u->var->lb, u->var->ub, R, 0, 0, 0, 0, 0, 0, R ? e->Rinvdepth : e->invdepth, 0, NULL, e->vars }; JL_GC_PUSH4(&u, &vb.lb, &vb.ub, &vb.innervars); e->vars = &vb; @@ -2318,67 +2317,31 @@ static jl_value_t *intersect_var(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int JL_GC_POP(); return ub; } - else if (bb->constraintkind == 0) { - if (!jl_is_typevar(bb->ub) && !jl_is_typevar(a)) { - if (try_subtype_in_env(bb->ub, a, e, 0, d)) - return (jl_value_t*)b; - } - return R ? intersect_aside(a, bb->ub, e, 1, d) : intersect_aside(bb->ub, a, e, 0, d); - } - else if (bb->concrete || bb->constraintkind == 1) { - jl_value_t *ub = R ? intersect_aside(a, bb->ub, e, 1, d) : intersect_aside(bb->ub, a, e, 0, d); - if (ub == jl_bottom_type) - return jl_bottom_type; - JL_GC_PUSH1(&ub); - if (!R && !subtype_bounds_in_env(bb->lb, a, e, 0, d)) { - // this fixes issue #30122. TODO: better fix for R flag. - JL_GC_POP(); - return jl_bottom_type; - } - JL_GC_POP(); - set_bound(&bb->ub, ub, b, e); - return (jl_value_t*)b; - } - else if (bb->constraintkind == 2) { - // TODO: removing this case fixes many test_brokens in test/subtype.jl - // but breaks other tests. - if (!subtype_bounds_in_env(a, bb->ub, e, 1, d)) { - // mark var as unsatisfiable by making it circular - bb->lb = (jl_value_t*)b; - return jl_bottom_type; - } - jl_value_t *lb = simple_join(bb->lb, a); - set_bound(&bb->lb, lb, b, e); - return a; - } - assert(bb->constraintkind == 3); jl_value_t *ub = R ? intersect_aside(a, bb->ub, e, 1, d) : intersect_aside(bb->ub, a, e, 0, d); if (ub == jl_bottom_type) return jl_bottom_type; - if (jl_is_typevar(a)) - return (jl_value_t*)b; - if (ub == a) { - if (bb->lb == jl_bottom_type) { - set_bound(&bb->ub, a, b, e); + if (bb->constraintkind == 0) { + JL_GC_PUSH1(&ub); + if (!jl_is_typevar(a) && try_subtype_in_env(bb->ub, a, e, 0, d)) { + JL_GC_POP(); return (jl_value_t*)b; } + JL_GC_POP(); return ub; } - else if (bb->ub == bb->lb) { - return ub; + else if (bb->constraintkind == 1) { + set_bound(&bb->ub, ub, b, e); + return (jl_value_t*)b; } - root = NULL; - JL_GC_PUSH2(&root, &ub); - save_env(e, &root, &se); - jl_value_t *ii = R ? intersect_aside(a, bb->lb, e, 1, d) : intersect_aside(bb->lb, a, e, 0, d); - if (ii == jl_bottom_type) { - restore_env(e, root, &se); - ii = (jl_value_t*)b; + assert(bb->constraintkind == 2); + if (!jl_is_typevar(a)) { + if (ub == a && bb->lb != jl_bottom_type) + return ub; + else if (jl_egal(bb->ub, bb->lb)) + return ub; set_bound(&bb->ub, ub, b, e); } - free_env(&se); - JL_GC_POP(); - return ii; + return (jl_value_t*)b; } // test whether `var` occurs inside constructors. `want_inv` tests only inside @@ -2422,7 +2385,7 @@ static int var_occurs_inside(jl_value_t *v, jl_tvar_t *var, int inside, int want } // Caller might not have rooted `res` -static jl_value_t *finish_unionall(jl_value_t *res JL_MAYBE_UNROOTED, jl_varbinding_t *vb, jl_stenv_t *e) +static jl_value_t *finish_unionall(jl_value_t *res JL_MAYBE_UNROOTED, jl_varbinding_t *vb, jl_unionall_t *u, jl_stenv_t *e) { jl_value_t *varval = NULL; jl_tvar_t *newvar = vb->var; @@ -2435,7 +2398,10 @@ static jl_value_t *finish_unionall(jl_value_t *res JL_MAYBE_UNROOTED, jl_varbind // given x<:T<:x, substitute x for T varval = vb->ub; } - else if (!vb->occurs_inv && is_leaf_bound(vb->ub)) { + // TODO: `vb.occurs_cov == 1` here allows substituting Tuple{<:X} => Tuple{X}, + // which is valid but changes some ambiguity errors so we don't need to do it yet. + else if ((/*vb->occurs_cov == 1 || */is_leaf_bound(vb->ub)) && + !var_occurs_invariant(u->body, u->var, 0)) { // replace T<:x with x in covariant position when possible varval = vb->ub; } @@ -2453,9 +2419,8 @@ static jl_value_t *finish_unionall(jl_value_t *res JL_MAYBE_UNROOTED, jl_varbind } } - // prefer generating a fresh typevar, to avoid repeated renaming if the result - // is compared to one of the intersected types later. - if (!varval) + // TODO: this can prevent us from matching typevar identities later + if (!varval && (vb->lb != vb->var->lb || vb->ub != vb->var->ub)) newvar = jl_new_typevar(vb->var->name, vb->lb, vb->ub); // remove/replace/rewrap free occurrences of this var in the environment @@ -2573,8 +2538,10 @@ static jl_value_t *intersect_unionall_(jl_value_t *t, jl_unionall_t *u, jl_stenv int envsize = 0; while (btemp != NULL) { envsize++; - if (envsize > 150) + if (envsize > 120) { + vb->limited = 1; return t; + } if (btemp->var == u->var || btemp->lb == (jl_value_t*)u->var || btemp->ub == (jl_value_t*)u->var) { u = rename_unionall(u); @@ -2624,7 +2591,7 @@ static jl_value_t *intersect_unionall_(jl_value_t *t, jl_unionall_t *u, jl_stenv } if (res != jl_bottom_type) // res is rooted by callee - res = finish_unionall(res, vb, e); + res = finish_unionall(res, vb, u, e); JL_GC_POP(); return res; } @@ -2633,16 +2600,21 @@ static jl_value_t *intersect_unionall(jl_value_t *t, jl_unionall_t *u, jl_stenv_ { jl_value_t *res=NULL, *res2=NULL, *save=NULL, *save2=NULL; jl_savedenv_t se, se2; - jl_varbinding_t vb = { u->var, u->var->lb, u->var->ub, R, 0, 0, 0, 0, 0, + jl_varbinding_t vb = { u->var, u->var->lb, u->var->ub, R, 0, 0, 0, 0, 0, 0, R ? e->Rinvdepth : e->invdepth, 0, NULL, e->vars }; JL_GC_PUSH6(&res, &save2, &vb.lb, &vb.ub, &save, &vb.innervars); save_env(e, &save, &se); res = intersect_unionall_(t, u, e, R, param, &vb); - if (res != jl_bottom_type) { + if (vb.limited) { + // if the environment got too big, avoid tree recursion and propagate the flag + if (e->vars) + e->vars->limited = 1; + } + else if (res != jl_bottom_type) { if (vb.concrete || vb.occurs_inv>1 || u->var->lb != jl_bottom_type || (vb.occurs_inv && vb.occurs_cov)) { restore_env(e, NULL, &se); vb.occurs_cov = vb.occurs_inv = 0; - vb.constraintkind = 3; + vb.constraintkind = vb.concrete ? 1 : 2; res = intersect_unionall_(t, u, e, R, param, &vb); } else if (vb.occurs_cov) { @@ -2652,17 +2624,10 @@ static jl_value_t *intersect_unionall(jl_value_t *t, jl_unionall_t *u, jl_stenv_ vb.lb = u->var->lb; vb.ub = u->var->ub; vb.constraintkind = 1; res2 = intersect_unionall_(t, u, e, R, param, &vb); - if (res2 == jl_bottom_type) { - restore_env(e, save, &se); - vb.occurs_cov = vb.occurs_inv = 0; - vb.lb = u->var->lb; vb.ub = u->var->ub; - vb.constraintkind = 2; - res2 = intersect_unionall_(t, u, e, R, param, &vb); - if (res2 == jl_bottom_type) - restore_env(e, save2, &se2); - } if (res2 != jl_bottom_type) res = res2; + else + restore_env(e, save2, &se2); free_env(&se2); } } @@ -3049,14 +3014,13 @@ static jl_value_t *intersect(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, int pa jl_value_t *ub=NULL, *lb=NULL; JL_GC_PUSH2(&lb, &ub); ub = intersect_aside(xub, yub, e, 0, xx ? xx->depth0 : 0); - if (xlb == y) + if (reachable_var(xlb, (jl_tvar_t*)y, e)) lb = ylb; else lb = simple_join(xlb, ylb); if (yy) { - if (!subtype_by_bounds(lb, y, e)) - yy->lb = lb; - if (!subtype_by_bounds(y, ub, e)) + yy->lb = lb; + if (!reachable_var(ub, (jl_tvar_t*)y, e)) yy->ub = ub; assert(yy->ub != y); assert(yy->lb != y); diff --git a/test/subtype.jl b/test/subtype.jl index 17d2b491003fec..5b8ebc6744e72e 100644 --- a/test/subtype.jl +++ b/test/subtype.jl @@ -587,7 +587,7 @@ function test_old() @test !(Type{Tuple{Nothing}} <: Tuple{Type{Nothing}}) end -const menagerie = +const easy_menagerie = Any[Bottom, Any, Int, Int8, Integer, Real, Array{Int,1}, AbstractArray{Int,1}, Tuple{Int,Vararg{Integer}}, Tuple{Integer,Vararg{Int}}, Tuple{}, @@ -607,12 +607,14 @@ const menagerie = Array{(@UnionAll T<:Int T), 1}, (@UnionAll T<:Real @UnionAll S<:AbstractArray{T,1} Tuple{T,S}), Union{Int,Ref{Union{Int,Int8}}}, - (@UnionAll T Union{Tuple{T,Array{T,1}}, Tuple{T,Array{Int,1}}}), ] -let new = Any[] - # add variants of each type - for T in menagerie +const hard_menagerie = + Any[(@UnionAll T Union{Tuple{T,Array{T,1}}, Tuple{T,Array{Int,1}}})] + +function add_variants!(types) + new = Any[] + for T in types push!(new, Ref{T}) push!(new, Tuple{T}) push!(new, Tuple{T,T}) @@ -620,9 +622,14 @@ let new = Any[] push!(new, @UnionAll S<:T S) push!(new, @UnionAll S<:T Ref{S}) end - append!(menagerie, new) + append!(types, new) end +add_variants!(easy_menagerie) +add_variants!(hard_menagerie) + +const menagerie = [easy_menagerie; hard_menagerie] + function test_properties() x→y = !x || y ¬T = @UnionAll X>:T Ref{X} @@ -1057,14 +1064,15 @@ function test_intersection() end function test_intersection_properties() - approx = Tuple{Vector{Vector{T}} where T, Vector{Vector{T}} where T} - for T in menagerie - for S in menagerie + for i in eachindex(menagerie) + T = menagerie[i] + for j in eachindex(menagerie) + S = menagerie[j] I = _type_intersect(T,S) I2 = _type_intersect(S,T) @test isequal_type(I, I2) - if I == approx - # TODO: some of these cases give a conservative answer + if i > length(easy_menagerie) || j > length(easy_menagerie) + # TODO: these cases give a conservative answer @test issub(I, T) || issub(I, S) else @test issub(I, T) && issub(I, S) @@ -1796,7 +1804,7 @@ let X1 = Tuple{AlmostLU, Vector{T}} where T, # TODO: the quality of this intersection is not great; for now just test that it # doesn't stack overflow @test I<:X1 || I<:X2 - actual = Tuple{AlmostLU{S, X} where X<:Matrix{S}, Vector{S}} where S<:Union{Float32, Float64} + actual = Tuple{Union{AlmostLU{S, X} where X<:Matrix{S}, AlmostLU{S, <:Matrix}}, Vector{S}} where S<:Union{Float32, Float64} @test I == actual end @@ -1898,8 +1906,8 @@ end # issue #39948 let A = Tuple{Array{Pair{T, JT} where JT<:Ref{T}, 1} where T, Vector}, I = typeintersect(A, Tuple{Vararg{Vector{T}}} where T) - @test_broken I <: A - @test_broken !Base.has_free_typevars(I) + @test I <: A + @test !Base.has_free_typevars(I) end # issue #8915 @@ -1927,3 +1935,27 @@ let A = Tuple{Ref{T}, Vararg{T}} where T, J = typeintersect(A, C) @test_broken J != Union{} end + +let A = Tuple{Dict{I,T}, I, T} where T where I, + B = Tuple{AbstractDict{I,T}, T, I} where T where I + # TODO: we should probably have I == T here + @test typeintersect(A, B) == Tuple{Dict{I,T}, I, T} where {I, T} +end + +let A = Tuple{UnionAll, Vector{Any}}, + B = Tuple{Type{T}, T} where T<:AbstractArray, + I = typeintersect(A, B) + @test !isconcretetype(I) + @test_broken I == Tuple{Type{T}, Vector{Any}} where T<:AbstractArray +end + +@testintersect(Tuple{Type{Vector{<:T}}, T} where {T<:Integer}, + Tuple{Type{T}, AbstractArray} where T<:Array, + Bottom) + +struct S40{_A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, _Z1, _Z2, _Z3, _Z4, _Z5, _Z6, _Z7, _Z8, _Z9, _Z10, _Z11, _Z12, _Z13, _Z14} +end + +@testintersect(Tuple{Type{S40{_A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, _Z1, _Z2, _Z3, _Z4, _Z5, _Z6, _Z7, _Z8, _Z9, _Z10, _Z11, _Z12, _Z13, _Z14}} where _Z14 where _Z13 where _Z12 where _Z11 where _Z10 where _Z9 where _Z8 where _Z7 where _Z6 where _Z5 where _Z4 where _Z3 where _Z2 where _Z1 where _Z where _Y where _X where _W where _V where _U where _T where _S where _R where _Q where _P where _O where _N where _M where _L where _K where _J where _I where _H where _G where _F where _E where _D where _C where _B where _A, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any}, + Tuple{Type{S40{A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27, A28, A29, A30, A31, A32, A33, A34, A35, A36, A37, A38, A39, A40} where A40 where A39 where A38 where A37 where A36 where A35 where A34 where A33 where A32 where A31 where A30 where A29 where A28 where A27 where A26 where A25 where A24 where A23 where A22 where A21 where A20 where A19 where A18 where A17 where A16 where A15 where A14 where A13 where A12 where A11 where A10 where A9 where A8 where A7 where A6 where A5 where A4 where A3 where A2 where A1}, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27, A28, A29, A30, A31, A32, A33, A34, A35, A36, A37, A38, A39, A40} where A40 where A39 where A38 where A37 where A36 where A35 where A34 where A33 where A32 where A31 where A30 where A29 where A28 where A27 where A26 where A25 where A24 where A23 where A22 where A21 where A20 where A19 where A18 where A17 where A16 where A15 where A14 where A13 where A12 where A11 where A10 where A9 where A8 where A7 where A6 where A5 where A4 where A3 where A2 where A1, + Bottom) From 71757cd618472d291b168671fc3f5e75611b4fd8 Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Thu, 12 Aug 2021 13:04:53 -0400 Subject: [PATCH 124/135] give wider/safer intersection result for vars used in both invariant and covariant position fixes #41738 --- src/subtype.c | 62 ++++++++++++++++++++++++++----------------------- test/subtype.jl | 18 +++++++++++--- 2 files changed, 48 insertions(+), 32 deletions(-) diff --git a/src/subtype.c b/src/subtype.c index 0a20b0db09b558..c3512eeb17daca 100644 --- a/src/subtype.c +++ b/src/subtype.c @@ -101,6 +101,7 @@ typedef struct jl_stenv_t { int ignore_free; // treat free vars as black boxes; used during intersection int intersection; // true iff subtype is being called from intersection int emptiness_only; // true iff intersection only needs to test for emptiness + int triangular; // when intersecting Ref{X} with Ref{<:Y} } jl_stenv_t; // state manipulation utilities @@ -1444,6 +1445,7 @@ static void init_stenv(jl_stenv_t *e, jl_value_t **env, int envsz) e->ignore_free = 0; e->intersection = 0; e->emptiness_only = 0; + e->triangular = 0; e->Lunions.depth = 0; e->Runions.depth = 0; e->Lunions.more = 0; e->Runions.more = 0; e->Lunions.used = 0; e->Runions.used = 0; @@ -2203,7 +2205,7 @@ static void set_bound(jl_value_t **bound, jl_value_t *val, jl_tvar_t *v, jl_sten return; jl_varbinding_t *btemp = e->vars; while (btemp != NULL) { - if (btemp->lb == (jl_value_t*)v && btemp->ub == (jl_value_t*)v && + if ((btemp->lb == (jl_value_t*)v || btemp->ub == (jl_value_t*)v) && in_union(val, (jl_value_t*)btemp->var)) return; btemp = btemp->prev; @@ -2255,6 +2257,21 @@ static int reachable_var(jl_value_t *x, jl_tvar_t *y, jl_stenv_t *e) return reachable_var(xv->ub, y, e) || reachable_var(xv->lb, y, e); } +// check whether setting v == t implies v == SomeType{v}, which is unsatisfiable. +static int check_unsat_bound(jl_value_t *t, jl_tvar_t *v, jl_stenv_t *e) JL_NOTSAFEPOINT +{ + if (var_occurs_inside(t, v, 0, 0)) + return 1; + jl_varbinding_t *btemp = e->vars; + while (btemp != NULL) { + if (btemp->lb == (jl_value_t*)v && btemp->ub == (jl_value_t*)v && + var_occurs_inside(t, btemp->var, 0, 0)) + return 1; + btemp = btemp->prev; + } + return 0; +} + static jl_value_t *intersect_var(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int8_t R, int param) { jl_varbinding_t *bb = lookup(e, b); @@ -2284,7 +2301,9 @@ static jl_value_t *intersect_var(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int ub = a; } else { + e->triangular++; ub = R ? intersect_aside(a, bb->ub, e, 1, d) : intersect_aside(bb->ub, a, e, 0, d); + e->triangular--; save_env(e, &root, &se); int issub = subtype_in_env_existential(bb->lb, ub, e, 0, d); restore_env(e, root, &se); @@ -2296,20 +2315,10 @@ static jl_value_t *intersect_var(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int } if (ub != (jl_value_t*)b) { if (jl_has_free_typevars(ub)) { - // constraint X == Ref{X} is unsatisfiable. also check variables set equal to X. - if (var_occurs_inside(ub, b, 0, 0)) { + if (check_unsat_bound(ub, b, e)) { JL_GC_POP(); return jl_bottom_type; } - jl_varbinding_t *btemp = e->vars; - while (btemp != NULL) { - if (btemp->lb == (jl_value_t*)b && btemp->ub == (jl_value_t*)b && - var_occurs_inside(ub, btemp->var, 0, 0)) { - JL_GC_POP(); - return jl_bottom_type; - } - btemp = btemp->prev; - } } bb->ub = ub; bb->lb = ub; @@ -2320,7 +2329,13 @@ static jl_value_t *intersect_var(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int jl_value_t *ub = R ? intersect_aside(a, bb->ub, e, 1, d) : intersect_aside(bb->ub, a, e, 0, d); if (ub == jl_bottom_type) return jl_bottom_type; - if (bb->constraintkind == 0) { + if (bb->constraintkind == 1 || e->triangular) { + if (e->triangular && check_unsat_bound(ub, b, e)) + return jl_bottom_type; + set_bound(&bb->ub, ub, b, e); + return (jl_value_t*)b; + } + else if (bb->constraintkind == 0) { JL_GC_PUSH1(&ub); if (!jl_is_typevar(a) && try_subtype_in_env(bb->ub, a, e, 0, d)) { JL_GC_POP(); @@ -2329,10 +2344,6 @@ static jl_value_t *intersect_var(jl_tvar_t *b, jl_value_t *a, jl_stenv_t *e, int JL_GC_POP(); return ub; } - else if (bb->constraintkind == 1) { - set_bound(&bb->ub, ub, b, e); - return (jl_value_t*)b; - } assert(bb->constraintkind == 2); if (!jl_is_typevar(a)) { if (ub == a && bb->lb != jl_bottom_type) @@ -2598,11 +2609,11 @@ static jl_value_t *intersect_unionall_(jl_value_t *t, jl_unionall_t *u, jl_stenv static jl_value_t *intersect_unionall(jl_value_t *t, jl_unionall_t *u, jl_stenv_t *e, int8_t R, int param) { - jl_value_t *res=NULL, *res2=NULL, *save=NULL, *save2=NULL; - jl_savedenv_t se, se2; + jl_value_t *res=NULL, *save=NULL; + jl_savedenv_t se; jl_varbinding_t vb = { u->var, u->var->lb, u->var->ub, R, 0, 0, 0, 0, 0, 0, R ? e->Rinvdepth : e->invdepth, 0, NULL, e->vars }; - JL_GC_PUSH6(&res, &save2, &vb.lb, &vb.ub, &save, &vb.innervars); + JL_GC_PUSH5(&res, &vb.lb, &vb.ub, &save, &vb.innervars); save_env(e, &save, &se); res = intersect_unionall_(t, u, e, R, param, &vb); if (vb.limited) { @@ -2617,18 +2628,11 @@ static jl_value_t *intersect_unionall(jl_value_t *t, jl_unionall_t *u, jl_stenv_ vb.constraintkind = vb.concrete ? 1 : 2; res = intersect_unionall_(t, u, e, R, param, &vb); } - else if (vb.occurs_cov) { - save_env(e, &save2, &se2); + else if (vb.occurs_cov && !var_occurs_invariant(u->body, u->var, 0)) { restore_env(e, save, &se); vb.occurs_cov = vb.occurs_inv = 0; - vb.lb = u->var->lb; vb.ub = u->var->ub; vb.constraintkind = 1; - res2 = intersect_unionall_(t, u, e, R, param, &vb); - if (res2 != jl_bottom_type) - res = res2; - else - restore_env(e, save2, &se2); - free_env(&se2); + res = intersect_unionall_(t, u, e, R, param, &vb); } } free_env(&se); diff --git a/test/subtype.jl b/test/subtype.jl index 5b8ebc6744e72e..d403716646de07 100644 --- a/test/subtype.jl +++ b/test/subtype.jl @@ -1577,7 +1577,7 @@ f31082(::Pair{B, C}, ::C, ::C) where {B, C} = 1 Tuple{Type{Val{T}},Int,T} where T) @testintersect(Tuple{Type{Val{T}},Integer,T} where T, Tuple{Type,Int,Integer}, - Tuple{Type{Val{T}},Int,T} where T<:Integer) + Tuple{Type{Val{T}},Int,Integer} where T) @testintersect(Tuple{Type{Val{T}},Integer,T} where T>:Integer, Tuple{Type,Int,Integer}, Tuple{Type{Val{T}},Int,Integer} where T>:Integer) @@ -1866,7 +1866,7 @@ let A = Tuple{Type{T} where T<:Ref, Ref, Union{T, Union{Ref{T}, T}} where T<:Ref I = typeintersect(A,B) # this was a case where <: disagreed with === (due to a badly-normalized type) @test I == typeintersect(A,B) - @test I == Tuple{Type{T}, Ref{T}, Union{Ref{T}, T}} where T<:Ref + @test I == Tuple{Type{T}, Ref{T}, Ref} where T<:Ref end # issue #39218 @@ -1946,7 +1946,7 @@ let A = Tuple{UnionAll, Vector{Any}}, B = Tuple{Type{T}, T} where T<:AbstractArray, I = typeintersect(A, B) @test !isconcretetype(I) - @test_broken I == Tuple{Type{T}, Vector{Any}} where T<:AbstractArray + @test I == Tuple{Type{T}, Vector{Any}} where T<:AbstractArray end @testintersect(Tuple{Type{Vector{<:T}}, T} where {T<:Integer}, @@ -1959,3 +1959,15 @@ end @testintersect(Tuple{Type{S40{_A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, _Z1, _Z2, _Z3, _Z4, _Z5, _Z6, _Z7, _Z8, _Z9, _Z10, _Z11, _Z12, _Z13, _Z14}} where _Z14 where _Z13 where _Z12 where _Z11 where _Z10 where _Z9 where _Z8 where _Z7 where _Z6 where _Z5 where _Z4 where _Z3 where _Z2 where _Z1 where _Z where _Y where _X where _W where _V where _U where _T where _S where _R where _Q where _P where _O where _N where _M where _L where _K where _J where _I where _H where _G where _F where _E where _D where _C where _B where _A, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any}, Tuple{Type{S40{A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27, A28, A29, A30, A31, A32, A33, A34, A35, A36, A37, A38, A39, A40} where A40 where A39 where A38 where A37 where A36 where A35 where A34 where A33 where A32 where A31 where A30 where A29 where A28 where A27 where A26 where A25 where A24 where A23 where A22 where A21 where A20 where A19 where A18 where A17 where A16 where A15 where A14 where A13 where A12 where A11 where A10 where A9 where A8 where A7 where A6 where A5 where A4 where A3 where A2 where A1}, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27, A28, A29, A30, A31, A32, A33, A34, A35, A36, A37, A38, A39, A40} where A40 where A39 where A38 where A37 where A36 where A35 where A34 where A33 where A32 where A31 where A30 where A29 where A28 where A27 where A26 where A25 where A24 where A23 where A22 where A21 where A20 where A19 where A18 where A17 where A16 where A15 where A14 where A13 where A12 where A11 where A10 where A9 where A8 where A7 where A6 where A5 where A4 where A3 where A2 where A1, Bottom) + +let A = Tuple{Any, Type{Ref{_A}} where _A}, + B = Tuple{Type{T}, Type{<:Union{Ref{T}, T}}} where T, + I = typeintersect(A, B) + @test I != Union{} + # TODO: this intersection result is still too narrow + @test_broken Tuple{Type{Ref{Integer}}, Type{Ref{Integer}}} <: I +end + +@testintersect(Tuple{Type{T}, T} where T<:(Tuple{Vararg{_A, _B}} where _B where _A), + Tuple{Type{Tuple{Vararg{_A, N}} where _A<:F}, Pair{N, F}} where F where N, + Bottom) From afc504bfc6ddfe315530e1dac6d98e83e19c5d02 Mon Sep 17 00:00:00 2001 From: Ann <49486372+annjc@users.noreply.github.com> Date: Thu, 26 Aug 2021 03:17:23 +0530 Subject: [PATCH 125/135] Docstring for `;` Uses (#41952) --- base/docs/basedocs.jl | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/base/docs/basedocs.jl b/base/docs/basedocs.jl index e580b728193b9a..d9625c914633be 100644 --- a/base/docs/basedocs.jl +++ b/base/docs/basedocs.jl @@ -974,9 +974,19 @@ kw"..." ; `;` has a similar role in Julia as in many C-like languages, and is used to delimit the -end of the previous statement. `;` is not necessary after new lines, but can be used to +end of the previous statement. + +`;` is not necessary at the end of a line, but can be used to separate statements on a single line or to join statements into a single expression. -`;` is also used to suppress output printing in the REPL and similar interfaces. + +Adding `;` at the end of a line in the REPL will suppress printing the result of that expression. + +In function declarations, and optionally in calls, `;` separates regular arguments from keywords. + +While constructing arrays, if the arguments inside the square brackets are separated by `;` +then their contents are vertically concatenated together. + +In the standard REPL, typing `;` on an empty line will switch to shell mode. # Examples ```julia @@ -993,6 +1003,19 @@ julia> foo(); julia> bar() "Hello, Mars!" + +julia> function plot(x, y; style="solid", width=1, color="black") + ### + end + +julia> [1 2; 3 4] +2×2 Matrix{Int64}: + 1 2 + 3 4 + +julia> ; # upon typing ;, the prompt changes (in place) to: shell> +shell> echo hello +hello ``` """ kw";" From 24450009edcd819238cc633ec3270be768716a13 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Thu, 26 Aug 2021 01:40:22 -0400 Subject: [PATCH 126/135] Fix #41975 - Dropped typecheck in GotoIfNot (#42010) Recall the reproducer from the issue: ``` julia> f() = (if nothing; end; unsafe_load(Ptr{Int}(0))) f (generic function with 1 method) julia> f() Unreachable reached at 0x7fb33bb50090 signal (4): Illegal instruction in expression starting at REPL[13]:1 unsafe_load at ./pointer.jl:105 [inlined] unsafe_load at ./pointer.jl:105 [inlined] ``` There were actually two places where we were dropping the GotoIfNot, one in type annotation after inference, one in SSA conversion. The one in SSA conversion was structural: When both branches target the same jump destination, the GotoIfNot would be dropped. This was fine in general, except that as shown above, GotoIfNot can actually itself have a side effect, namely throwing a type error if the condition is not a boolean. Thus in order to actually drop the node we need to prove that the error check does not fire. The reason we want to drop the GotoIfNot node here is that IRCode has an invariant that every basic block is in the predecessor list only once (otherwise PhiNodes would have to carry extra state regarding which branch they refer to). To fix this, insert an `Expr(:call, typecheck, _, Bool)` when dropping the GotoIfNot. We do lose the ability to distinguish the GotoIfNot from literal typechecks as a result, but at the moment they generate identical errors. If we ever wanted to dinstinguish them, we could create another typecheck intrinsic that throws a different error or use an approach like #41994. --- base/compiler/ssair/slot2ssa.jl | 2 +- base/compiler/typeinfer.jl | 2 +- test/compiler/ssair.jl | 4 ++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/base/compiler/ssair/slot2ssa.jl b/base/compiler/ssair/slot2ssa.jl index 6ca17be2f0a83a..777e7e2bb0af7f 100644 --- a/base/compiler/ssair/slot2ssa.jl +++ b/base/compiler/ssair/slot2ssa.jl @@ -825,7 +825,7 @@ function construct_ssa!(ci::CodeInfo, ir::IRCode, domtree::DomTree, defuse, new_dest = block_for_inst(cfg, stmt.dest) if new_dest == bb+1 # Drop this node - it's a noop - new_code[idx] = stmt.cond + new_code[idx] = Expr(:call, GlobalRef(Core, :typeassert), stmt.cond, GlobalRef(Core, :Bool)) else new_code[idx] = GotoIfNot(stmt.cond, new_dest) end diff --git a/base/compiler/typeinfer.jl b/base/compiler/typeinfer.jl index a3895c380f8bd0..a9ab2d231c13c5 100644 --- a/base/compiler/typeinfer.jl +++ b/base/compiler/typeinfer.jl @@ -633,7 +633,7 @@ function type_annotate!(sv::InferenceState, run_optimizer::Bool) expr = body[i] if isa(expr, GotoIfNot) if !isa(states[expr.dest], VarTable) - body[i] = expr.cond + body[i] = Expr(:call, GlobalRef(Core, :typeassert), expr.cond, GlobalRef(Core, :Bool)) end end end diff --git a/test/compiler/ssair.jl b/test/compiler/ssair.jl index f90bb71e291d09..17a0753eddc640 100644 --- a/test/compiler/ssair.jl +++ b/test/compiler/ssair.jl @@ -310,3 +310,7 @@ let cfg = CFG(BasicBlock[ Compiler.domtree_insert_edge!(domtree, cfg.blocks, 1, 3) @test domtree.idoms_bb == Compiler.naive_idoms(cfg.blocks) == [0, 1, 1, 3, 1, 4] end + +# Issue #41975 - SSA conversion drops type check +f_if_typecheck() = (if nothing; end; unsafe_load(Ptr{Int}(0))) +@test_throws TypeError f_if_typecheck() From f1b5abc8d173b9df222f4b7669f47b76bd3c5fed Mon Sep 17 00:00:00 2001 From: Nicholas Bauer Date: Thu, 26 Aug 2021 11:24:51 -0400 Subject: [PATCH 127/135] Improve performance of Symbol concatenation (#41992) --- base/strings/substring.jl | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/base/strings/substring.jl b/base/strings/substring.jl index 0da09f36be9310..7cc4c53a6b6619 100644 --- a/base/strings/substring.jl +++ b/base/strings/substring.jl @@ -205,7 +205,13 @@ end return n end -function string(a::Union{Char, String, SubString{String}}...) +@inline function __unsafe_string!(out, s::Symbol, offs::Integer) + n = sizeof(s) + GC.@preserve s out unsafe_copyto!(pointer(out, offs), unsafe_convert(Ptr{UInt8},s), n) + return n +end + +function string(a::Union{Char, String, SubString{String}, Symbol}...) n = 0 for v in a if v isa Char From f7506aace35133b6224b13866eca56e799f5929c Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Fri, 27 Aug 2021 00:41:03 +0900 Subject: [PATCH 128/135] export `jl_resolve_globals_in_ir` (#42013) This would be very useful for external `AbstractInterpreter`s to infer (and possibly even optimize) toplevel thunks. --- src/jl_exported_funcs.inc | 2 +- src/method.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/jl_exported_funcs.inc b/src/jl_exported_funcs.inc index 256fdfeaa0890d..99e7eb09aaa4c7 100644 --- a/src/jl_exported_funcs.inc +++ b/src/jl_exported_funcs.inc @@ -150,6 +150,7 @@ XX(jl_exit_on_sigint) \ XX(jl_exit_threaded_region) \ XX(jl_expand) \ + XX(jl_resolve_globals_in_ir) \ XX(jl_expand_and_resolve) \ XX(jl_expand_stmt) \ XX(jl_expand_stmt_with_loc) \ @@ -550,4 +551,3 @@ XX(jl_vprintf) \ XX(jl_wakeup_thread) \ XX(jl_yield) \ - diff --git a/src/method.c b/src/method.c index 22145a43498533..9c255f786b74da 100644 --- a/src/method.c +++ b/src/method.c @@ -243,7 +243,7 @@ static jl_value_t *resolve_globals(jl_value_t *expr, jl_module_t *module, jl_sve return expr; } -void jl_resolve_globals_in_ir(jl_array_t *stmts, jl_module_t *m, jl_svec_t *sparam_vals, +JL_DLLEXPORT void jl_resolve_globals_in_ir(jl_array_t *stmts, jl_module_t *m, jl_svec_t *sparam_vals, int binding_effects) { size_t i, l = jl_array_len(stmts); From 24876b7912900e8c5e7d1701ca78aebce0f3f038 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Thu, 26 Aug 2021 11:41:16 -0400 Subject: [PATCH 129/135] streams: disable half-duplex operation support (#42005) A stream can continue to be read after closewrite, but cannot continue to be written to after seeing EOF. Replaces #42004 Replaces #41983 Fixes #41942 Refs #40783 --- base/stream.jl | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/base/stream.jl b/base/stream.jl index 6e433b771f0d2f..f4bd8b29fc981d 100644 --- a/base/stream.jl +++ b/base/stream.jl @@ -467,7 +467,9 @@ function shutdown(s::LibuvStream) end iolock_end() unpreserve_handle(ct) - if isopen(s) && (s.status == StatusEOF && !isa(s, TTY)) || ccall(:uv_is_readable, Cint, (Ptr{Cvoid},), s.handle) == 0 + end + if isopen(s) + if status < 0 || ccall(:uv_is_readable, Cint, (Ptr{Cvoid},), s.handle) == 0 close(s) end end @@ -658,9 +660,9 @@ function uv_readcb(handle::Ptr{Cvoid}, nread::Cssize_t, buf::Ptr{Cvoid}) notify(stream.cond) elseif nread == UV_EOF # libuv called uv_stop_reading already if stream.status != StatusClosing - if stream isa TTY || ccall(:uv_is_writable, Cint, (Ptr{Cvoid},), stream.handle) != 0 - # stream can still be used either by reseteof or write - stream.status = StatusEOF + stream.status = StatusEOF + if stream isa TTY # TODO: || ccall(:uv_is_writable, Cint, (Ptr{Cvoid},), stream.handle) != 0 + # stream can still be used either by reseteof # TODO: or write notify(stream.cond) else # underlying stream is no longer useful: begin finalization From 82c4a2739f97c942508b29e7d946a0504f45fb23 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Thu, 26 Aug 2021 11:42:14 -0400 Subject: [PATCH 130/135] fix ptrhash_remove (#42009) Same bug as 5e57c214f872083ccacafa0f753e794ec654a21a (#26833), same fix. --- src/Makefile | 4 +- src/dump.c | 5 +- src/support/htable.inc | 112 ++++++++++++++++++++++------------------- 3 files changed, 65 insertions(+), 56 deletions(-) diff --git a/src/Makefile b/src/Makefile index fe5fc81328d1aa..ed0cbaf9c8c9ae 100644 --- a/src/Makefile +++ b/src/Makefile @@ -278,10 +278,10 @@ $(addprefix $(BUILDDIR)/,threading.o threading.dbg.obj gc.o gc.dbg.obj init.c in $(addprefix $(BUILDDIR)/,APInt-C.o APInt-C.dbg.obj runtime_intrinsics.o runtime_intrinsics.dbg.obj): $(SRCDIR)/APInt-C.h # archive library file rules -$(BUILDDIR)/support/libsupport.a: $(addprefix $(SRCDIR)/support/,*.h *.c *.S) $(SRCDIR)/support/*.c +$(BUILDDIR)/support/libsupport.a: $(addprefix $(SRCDIR)/support/,*.h *.c *.S *.inc) $(SRCDIR)/support/*.c $(MAKE) -C $(SRCDIR)/support BUILDDIR='$(abspath $(BUILDDIR)/support)' -$(BUILDDIR)/support/libsupport-debug.a: $(addprefix $(SRCDIR)/support/,*.h *.c *.S) $(SRCDIR)/support/*.c +$(BUILDDIR)/support/libsupport-debug.a: $(addprefix $(SRCDIR)/support/,*.h *.c *.S *.inc) $(SRCDIR)/support/*.c $(MAKE) -C $(SRCDIR)/support debug BUILDDIR='$(abspath $(BUILDDIR)/support)' $(FLISP_EXECUTABLE_release): $(BUILDDIR)/flisp/libflisp.a diff --git a/src/dump.c b/src/dump.c index af3290a5114eb0..1cdf0787648c8c 100644 --- a/src/dump.c +++ b/src/dump.c @@ -2058,14 +2058,14 @@ static void jl_insert_backedges(jl_array_t *list, jl_array_t *targets) while (codeinst) { if (codeinst->min_world > 0) codeinst->max_world = ~(size_t)0; - ptrhash_put(&new_code_instance_validate, codeinst, HT_NOTFOUND); // mark it as handled + ptrhash_remove(&new_code_instance_validate, codeinst); // mark it as handled codeinst = jl_atomic_load_relaxed(&codeinst->next); } } else { jl_code_instance_t *codeinst = caller->cache; while (codeinst) { - ptrhash_put(&new_code_instance_validate, codeinst, HT_NOTFOUND); // should be left invalid + ptrhash_remove(&new_code_instance_validate, codeinst); // should be left invalid codeinst = jl_atomic_load_relaxed(&codeinst->next); } if (_jl_debug_method_invalidation) { @@ -2084,7 +2084,6 @@ static void validate_new_code_instances(void) for (i = 0; i < new_code_instance_validate.size; i += 2) { if (new_code_instance_validate.table[i+1] != HT_NOTFOUND) { ((jl_code_instance_t*)new_code_instance_validate.table[i])->max_world = ~(size_t)0; - new_code_instance_validate.table[i+1] = HT_NOTFOUND; } } } diff --git a/src/support/htable.inc b/src/support/htable.inc index fa59624a4998f5..7a9be2514e2f0d 100644 --- a/src/support/htable.inc +++ b/src/support/htable.inc @@ -13,67 +13,77 @@ static void **HTNAME##_lookup_bp_r(htable_t *h, void *key, void *ctx) \ { \ uint_t hv; \ - size_t i, orig, index, iter; \ + size_t i, orig, index, iter, empty_slot; \ size_t newsz, sz = hash_size(h); \ size_t maxprobe = max_probe(sz); \ void **tab = h->table; \ void **ol; \ \ hv = HFUNC((uintptr_t)key, ctx); \ - retry_bp: \ - iter = 0; \ - index = (size_t)(hv & (sz-1)) * 2; \ - sz *= 2; \ - orig = index; \ - \ - do { \ - if (tab[index+1] == HT_NOTFOUND) { \ - tab[index] = key; \ - return &tab[index+1]; \ + while (1) { \ + iter = 0; \ + index = (size_t)(hv & (sz-1)) * 2; \ + sz *= 2; \ + orig = index; \ + empty_slot = -1; \ + \ + do { \ + if (tab[index] == HT_NOTFOUND) { \ + if (empty_slot == -1) \ + empty_slot = index; \ + break; \ + } \ + if (tab[index+1] == HT_NOTFOUND) { \ + if (empty_slot == -1) \ + empty_slot = index; \ + } \ + \ + if (EQFUNC(key, tab[index], ctx)) \ + return &tab[index+1]; \ + \ + index = (index+2) & (sz-1); \ + iter++; \ + if (iter > maxprobe) \ + break; \ + } while (index != orig); \ + \ + if (empty_slot != -1) { \ + tab[empty_slot] = key; \ + return &tab[empty_slot+1]; \ } \ \ - if (EQFUNC(key, tab[index], ctx)) \ - return &tab[index+1]; \ - \ - index = (index+2) & (sz-1); \ - iter++; \ - if (iter > maxprobe) \ - break; \ - } while (index != orig); \ - \ - /* table full */ \ - /* quadruple size, rehash, retry the insert */ \ - /* it's important to grow the table really fast; otherwise we waste */ \ - /* lots of time rehashing all the keys over and over. */ \ - sz = h->size; \ - ol = h->table; \ - if (sz < HT_N_INLINE) \ - newsz = HT_N_INLINE; \ - else if (sz >= (1<<19) || (sz <= (1<<8))) \ - newsz = sz<<1; \ - else \ - newsz = sz<<2; \ - /*printf("trying to allocate %d words.\n", newsz); fflush(stdout);*/ \ - tab = (void**)LLT_ALLOC(newsz*sizeof(void*)); \ - if (tab == NULL) \ - return NULL; \ - for(i=0; i < newsz; i++) \ - tab[i] = HT_NOTFOUND; \ - h->table = tab; \ - h->size = newsz; \ - for(i=0; i < sz; i+=2) { \ - if (ol[i+1] != HT_NOTFOUND) { \ - (*HTNAME##_lookup_bp_r(h, ol[i], ctx)) = ol[i+1]; \ + /* table full */ \ + /* quadruple size, rehash, retry the insert */ \ + /* it's important to grow the table really fast; otherwise we waste */ \ + /* lots of time rehashing all the keys over and over. */ \ + sz = h->size; \ + ol = h->table; \ + if (sz < HT_N_INLINE) \ + newsz = HT_N_INLINE; \ + else if (sz >= (1<<19) || (sz <= (1<<8))) \ + newsz = sz<<1; \ + else \ + newsz = sz<<2; \ + /*printf("trying to allocate %d words.\n", newsz); fflush(stdout);*/ \ + tab = (void**)LLT_ALLOC(newsz*sizeof(void*)); \ + if (tab == NULL) \ + return NULL; \ + for (i = 0; i < newsz; i++) \ + tab[i] = HT_NOTFOUND; \ + h->table = tab; \ + h->size = newsz; \ + for (i = 0; i < sz; i += 2) { \ + if (ol[i+1] != HT_NOTFOUND) { \ + (*HTNAME##_lookup_bp_r(h, ol[i], ctx)) = ol[i+1]; \ + } \ } \ - } \ - if (ol != &h->_space[0]) \ - LLT_FREE(ol); \ + if (ol != &h->_space[0]) \ + LLT_FREE(ol); \ \ - sz = hash_size(h); \ - maxprobe = max_probe(sz); \ - tab = h->table; \ - \ - goto retry_bp; \ + sz = hash_size(h); \ + maxprobe = max_probe(sz); \ + tab = h->table; \ + } \ \ return NULL; \ } \ From 846492960fdbc9e3806e8bb8336cad4d559fa733 Mon Sep 17 00:00:00 2001 From: Arun sanganal <74652697+ArunSanganal@users.noreply.github.com> Date: Thu, 26 Aug 2021 21:12:53 +0530 Subject: [PATCH 131/135] REPL: tab completion for non-struct types (#41679) --- stdlib/REPL/src/REPLCompletions.jl | 2 +- stdlib/REPL/test/replcompletions.jl | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/stdlib/REPL/src/REPLCompletions.jl b/stdlib/REPL/src/REPLCompletions.jl index 77d5d87e41b8cf..6845f1bc284fd4 100644 --- a/stdlib/REPL/src/REPLCompletions.jl +++ b/stdlib/REPL/src/REPLCompletions.jl @@ -144,7 +144,7 @@ function complete_symbol(sym::String, ffunc, context_module::Module=Main) if isa(b, Module) mod = b lookup_module = true - elseif Base.isstructtype(typeof(b)) + else lookup_module = false t = typeof(b) end diff --git a/stdlib/REPL/test/replcompletions.jl b/stdlib/REPL/test/replcompletions.jl index 14f6de445c0838..671afd6c30073e 100644 --- a/stdlib/REPL/test/replcompletions.jl +++ b/stdlib/REPL/test/replcompletions.jl @@ -32,6 +32,10 @@ let ex = quote :() end + primitive type NonStruct 8 end + Base.propertynames(::NonStruct) = (:a, :b, :c) + x = reinterpret(NonStruct, 0x00) + # Support non-Dict AbstractDicts, #19441 mutable struct CustomDict{K, V} <: AbstractDict{K, V} mydict::Dict{K, V} @@ -1145,6 +1149,11 @@ let s = "test_dict[\"ab" @test c == Any["\"abc\"", "\"abcd\""] end +let s = "CompletionFoo.x." + c, r = test_complete(s) + @test "a" in c +end + # https://github.com/JuliaLang/julia/issues/27184 let (test_complete("@noexist."); @test true) From 08f342230e056c118dedd9889c558ebcbbb26603 Mon Sep 17 00:00:00 2001 From: Troels Nielsen Date: Thu, 26 Aug 2021 17:44:27 +0200 Subject: [PATCH 132/135] codegen: parameter attributes on CFunction closures sticks (#41827) When CFunction closures are created an extra argument is added to the function signature for holding the closure. Make sure that the parameter attributes on already existing parameters are not shifted when adding that parameter. --- src/codegen.cpp | 41 ++++++++++++++++++++++++++++++++++++++++- test/ccall.jl | 20 ++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index 744d29629b0cae..3292df745d90b4 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -5180,9 +5180,48 @@ static Function* gen_cfun_wrapper( // add nest parameter (pointer to jl_value_t* data array) after sret arg assert(closure_types); std::vector fargt_sig(sig.fargt_sig); + fargt_sig.insert(fargt_sig.begin() + sig.sret, T_pprjlvalue); + + // Shift LLVM attributes for parameters one to the right, as + // we are adding the extra nest parameter after sret arg. + std::vector> newAttributes; + newAttributes.reserve(attributes.getNumAttrSets() + 1); + auto it = attributes.index_begin(); + + // Skip past FunctionIndex + if (it == AttributeList::AttrIndex::FunctionIndex) { + ++it; + } + + // Move past ReturnValue and parameter return value + for (;it < AttributeList::AttrIndex::FirstArgIndex + sig.sret; ++it) { + if (attributes.hasAttributes(it)) { + newAttributes.emplace_back(it, attributes.getAttributes(it)); + } + } + + // Add the new nest attribute + AttrBuilder attrBuilder; + attrBuilder.addAttribute(Attribute::Nest); + newAttributes.emplace_back(it, AttributeSet::get(jl_LLVMContext, attrBuilder)); + + // Shift forward the rest of the attributes + for(;it < attributes.index_end(); ++it) { + if (attributes.hasAttributes(it)) { + newAttributes.emplace_back(it + 1, attributes.getAttributes(it)); + } + } + + // Remember to add back FunctionIndex + if (attributes.hasAttributes(AttributeList::AttrIndex::FunctionIndex)) { + newAttributes.emplace_back(AttributeList::AttrIndex::FunctionIndex, + attributes.getAttributes(AttributeList::AttrIndex::FunctionIndex)); + } + + // Create the new AttributeList + attributes = AttributeList::get(jl_LLVMContext, newAttributes); functype = FunctionType::get(sig.sret ? T_void : sig.prt, fargt_sig, /*isVa*/false); - attributes = attributes.addAttribute(jl_LLVMContext, 1 + sig.sret, Attribute::Nest); } else { functype = sig.functype(); diff --git a/test/ccall.jl b/test/ccall.jl index 02d005108459e7..01f0f4f651aa8a 100644 --- a/test/ccall.jl +++ b/test/ccall.jl @@ -982,6 +982,26 @@ for (t, v) in ((Complex{Int32}, :ci32), (Complex{Int64}, :ci64), end end + +#issue 40164 +@testset "llvm parameter attributes on cfunction closures" begin + struct Struct40164 + x::Cdouble + y::Cdouble + z::Cdouble + end + + function test_40164() + ret = Struct40164[] + f = x::Struct40164 -> (push!(ret, x); nothing) + f_c = @cfunction($f, Cvoid, (Struct40164,)) + ccall(f_c.ptr, Ptr{Cvoid}, (Struct40164,), Struct40164(0, 1, 2)) + ret + end + + @test test_40164() == [Struct40164(0, 1, 2)] +end + else @test_broken "cfunction: no support for closures on this platform" From c298e4ee996c4d52a0ceb17c209831042f72e6c0 Mon Sep 17 00:00:00 2001 From: Chris Foster Date: Fri, 27 Aug 2021 01:44:48 +1000 Subject: [PATCH 133/135] Rename shutdown() to closewrite() (#41995) This name was suggested in #24526 and * Has a good analogy to close(), so people are likely to be able to guess what it means. * Is more specific to IO (conversely, it's easy to imagine shutdown() being wanted for any number of things unrelated to closing the write side of an IO stream). --- NEWS.md | 2 +- base/exports.jl | 2 +- base/io.jl | 8 ++++---- base/iobuffer.jl | 4 ++-- base/process.jl | 2 +- base/stream.jl | 4 ++-- doc/src/base/io-network.md | 2 +- stdlib/Sockets/test/runtests.jl | 4 ++-- test/iobuffer.jl | 4 ++-- 9 files changed, 16 insertions(+), 16 deletions(-) diff --git a/NEWS.md b/NEWS.md index 6ac3546e969bb1..ae6880b5a8d0dc 100644 --- a/NEWS.md +++ b/NEWS.md @@ -49,7 +49,7 @@ Standard library changes 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]) -* TCP socket objects now expose `shutdown` functionality and support half-open mode usage ([#40783]). +* TCP socket objects now expose `closewrite` functionality and support half-open mode usage ([#40783]). #### InteractiveUtils * A new macro `@time_imports` for reporting any time spent importing packages and their dependencies ([#41612]) diff --git a/base/exports.jl b/base/exports.jl index da0019ab469877..36baa386d5510a 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -803,7 +803,7 @@ export # I/O and events close, - shutdown, + closewrite, countlines, eachline, readeach, diff --git a/base/io.jl b/base/io.jl index 2eface1ca94581..9e7248c55c43ad 100644 --- a/base/io.jl +++ b/base/io.jl @@ -62,7 +62,7 @@ Close an I/O stream. Performs a [`flush`](@ref) first. function close end """ - shutdown(stream) + closewrite(stream) Shutdown the write half of a full-duplex I/O stream. Performs a [`flush`](@ref) first. Notify the other end that no more data will be written to the underlying @@ -76,12 +76,12 @@ julia> write(io, "request"); julia> # calling `read(io)` here would block forever -julia> shutdown(io); +julia> closewrite(io); julia> read(io, String) "request" """ -function shutdown end +function closewrite end """ flush(stream) @@ -410,7 +410,7 @@ end function pipe_reader end function pipe_writer end -for f in (:flush, :shutdown, :iswritable) +for f in (:flush, :closewrite, :iswritable) @eval $(f)(io::AbstractPipe) = $(f)(pipe_writer(io)::IO) end write(io::AbstractPipe, byte::UInt8) = write(pipe_writer(io)::IO, byte) diff --git a/base/iobuffer.jl b/base/iobuffer.jl index f65ed3f894fe00..e08a019d84a2ca 100644 --- a/base/iobuffer.jl +++ b/base/iobuffer.jl @@ -334,9 +334,9 @@ end eof(io::GenericIOBuffer) = (io.ptr-1 == io.size) -function shutdown(io::GenericIOBuffer) +function closewrite(io::GenericIOBuffer) io.writable = false - # OR throw(_UVError("shutdown", UV_ENOTSOCK)) + # OR throw(_UVError("closewrite", UV_ENOTSOCK)) nothing end diff --git a/base/process.jl b/base/process.jl index 6be7099f94f358..666c94c49a7fa0 100644 --- a/base/process.jl +++ b/base/process.jl @@ -275,7 +275,7 @@ function setup_stdio(stdio::Union{IOBuffer, BufferStream}, child_readable::Bool) @warn "Process error" exception=(ex, catch_backtrace()) finally close(parent) - child_readable || shutdown(stdio) + child_readable || closewrite(stdio) end end catch ex diff --git a/base/stream.jl b/base/stream.jl index f4bd8b29fc981d..b9bfa7aee1d960 100644 --- a/base/stream.jl +++ b/base/stream.jl @@ -433,7 +433,7 @@ function wait_readnb(x::LibuvStream, nb::Int) nothing end -function shutdown(s::LibuvStream) +function closewrite(s::LibuvStream) iolock_begin() check_open(s) req = Libc.malloc(_sizeof_uv_shutdown) @@ -1478,7 +1478,7 @@ end isopen(s::BufferStream) = s.status != StatusClosed -shutdown(s::BufferStream) = close(s) +closewrite(s::BufferStream) = close(s) function close(s::BufferStream) lock(s.cond) do diff --git a/doc/src/base/io-network.md b/doc/src/base/io-network.md index 8b2ea3c4c2412f..ba7d779f9152ae 100644 --- a/doc/src/base/io-network.md +++ b/doc/src/base/io-network.md @@ -13,7 +13,7 @@ Base.take!(::Base.GenericIOBuffer) Base.fdio Base.flush Base.close -Base.shutdown +Base.closewrite Base.write Base.read Base.read! diff --git a/stdlib/Sockets/test/runtests.jl b/stdlib/Sockets/test/runtests.jl index 328ea929f4b4ba..90a281050d150a 100644 --- a/stdlib/Sockets/test/runtests.jl +++ b/stdlib/Sockets/test/runtests.jl @@ -566,7 +566,7 @@ end end let s = Sockets.connect(addr) @test iswritable(s) - shutdown(s) + closewrite(s) @test !iswritable(s) close(s) end @@ -578,7 +578,7 @@ end end @test iswritable(s) write(s, "hello world\n") - shutdown(s) + closewrite(s) @test !iswritable(s) @test isreadable(s) @test read(s, String) == "hello world\n" diff --git a/test/iobuffer.jl b/test/iobuffer.jl index 5514b6dc03f7fa..d8211aa7086b34 100644 --- a/test/iobuffer.jl +++ b/test/iobuffer.jl @@ -46,7 +46,7 @@ bufcontents(io::Base.GenericIOBuffer) = unsafe_string(pointer(io.data), io.size) @test String(take!(io)) == "" @test write(io, ComplexF64(0)) === 16 @test write(io, Rational{Int64}(1//2)) === 16 - @test shutdown(io) === nothing + @test closewrite(io) === nothing @test_throws ArgumentError write(io, UInt8[0]) @test eof(io) @test close(io) === nothing @@ -253,7 +253,7 @@ end @test !eof(bstream) read!(bstream,c) @test c == a[3:10] - @test shutdown(bstream) === nothing + @test closewrite(bstream) === nothing @test eof(bstream) @test bytesavailable(bstream) == 0 @test close(bstream) === nothing From aa5ab4a954ea13ce098c21d45b4c6fcacd139efb Mon Sep 17 00:00:00 2001 From: Lyndon White Date: Thu, 26 Aug 2021 16:53:03 +0100 Subject: [PATCH 134/135] Make section on returned function pointer say to use ccall (#41962) --- doc/src/manual/calling-c-and-fortran-code.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/src/manual/calling-c-and-fortran-code.md b/doc/src/manual/calling-c-and-fortran-code.md index 89d535fd543441..ccad2cce29dfe3 100644 --- a/doc/src/manual/calling-c-and-fortran-code.md +++ b/doc/src/manual/calling-c-and-fortran-code.md @@ -721,7 +721,8 @@ For translating a C return type to Julia: * `Ptr{T}`, where `T` is the Julia type corresponding to `T` * `T (*)(...)` (e.g. a pointer to a function) - * `Ptr{Cvoid}` (you may need to use [`@cfunction`](@ref) explicitly to create this pointer) + * `Ptr{Cvoid}` to call this directly from Julia you will need to pass this as the first argument to [`ccall`](@ref). + See [Indirect Calls](@ref). ### Passing Pointers for Modifying Inputs From 690eae23ca0f2d2a6dbca2771d94db3daf851198 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Thu, 26 Aug 2021 12:08:48 -0400 Subject: [PATCH 135/135] atomics: optimize modify operation (partially) (#41859) Optimize the load/store portion of the operations, but not yet the invoke part. --- src/cgutils.cpp | 295 ++++++++++++++++++++++++++------------- src/codegen.cpp | 30 ++-- src/intrinsics.cpp | 25 ++-- src/runtime_intrinsics.c | 22 ++- test/intrinsics.jl | 4 +- 5 files changed, 251 insertions(+), 125 deletions(-) diff --git a/src/cgutils.cpp b/src/cgutils.cpp index 95bb7f46a21e5d..48f0005440d5da 100644 --- a/src/cgutils.cpp +++ b/src/cgutils.cpp @@ -1542,12 +1542,23 @@ static jl_cgval_t typed_load(jl_codectx_t &ctx, Value *ptr, Value *idx_0based, j } static jl_cgval_t typed_store(jl_codectx_t &ctx, - Value *ptr, Value *idx_0based, const jl_cgval_t &rhs, const jl_cgval_t &cmp, + Value *ptr, Value *idx_0based, jl_cgval_t rhs, jl_cgval_t cmp, jl_value_t *jltype, MDNode *tbaa, MDNode *aliasscope, Value *parent, // for the write barrier, NULL if no barrier needed bool isboxed, AtomicOrdering Order, AtomicOrdering FailOrder, unsigned alignment, - bool needlock, bool issetfield, bool isreplacefield, bool maybe_null_if_boxed) -{ + bool needlock, bool issetfield, bool isreplacefield, bool isswapfield, bool ismodifyfield, + bool maybe_null_if_boxed, const std::string &fname) +{ + auto newval = [&](const jl_cgval_t &lhs) { + jl_cgval_t argv[3] = { cmp, lhs, rhs }; + Value *callval = emit_jlcall(ctx, jlapplygeneric_func, nullptr, argv, 3, JLCALL_F_CC); + argv[0] = mark_julia_type(ctx, callval, true, jl_any_type); + if (!jl_subtype(argv[0].typ, jltype)) { + emit_typecheck(ctx, argv[0], jltype, fname + "typed_store"); + argv[0] = update_julia_type(ctx, argv[0], jltype); + } + return argv[0]; + }; assert(!needlock || parent != nullptr); Type *elty = isboxed ? T_prjlvalue : julia_type_to_llvm(ctx, jltype); if (type_is_ghost(elty)) { @@ -1563,9 +1574,15 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx, jl_datatype_t *rettyp = jl_apply_cmpswap_type(jltype); return emit_new_struct(ctx, (jl_value_t*)rettyp, 2, argv); } - else { + else if (isswapfield) { return ghostValue(jltype); } + else { // modifyfield + jl_cgval_t oldval = ghostValue(jltype); + jl_cgval_t argv[2] = { oldval, newval(oldval) }; + jl_datatype_t *rettyp = jl_apply_modify_type(jltype); + return emit_new_struct(ctx, (jl_value_t*)rettyp, 2, argv); + } } Value *intcast = nullptr; if (!isboxed && Order != AtomicOrdering::NotAtomic && !elty->isIntOrPtrTy()) { @@ -1582,13 +1599,15 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx, if (nb != nb2) elty = Type::getIntNTy(jl_LLVMContext, nb2); } - Value *r; - if (!isboxed) - r = emit_unbox(ctx, realelty, rhs, jltype); - else - r = boxed(ctx, rhs); - if (realelty != elty) - r = ctx.builder.CreateZExt(r, elty); + Value *r = nullptr; + if (issetfield || isswapfield || isreplacefield) { + if (!isboxed) + r = emit_unbox(ctx, realelty, rhs, jltype); + else + r = boxed(ctx, rhs); + if (realelty != elty) + r = ctx.builder.CreateZExt(r, elty); + } Type *ptrty = PointerType::get(elty, ptr->getType()->getPointerAddressSpace()); if (ptr->getType() != ptrty) ptr = ctx.builder.CreateBitCast(ptr, ptrty); @@ -1598,33 +1617,22 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx, alignment = sizeof(void*); else if (!alignment) alignment = julia_alignment(jltype); - Instruction *instr = nullptr; + Value *instr = nullptr; Value *Compare = nullptr; Value *Success = nullptr; - BasicBlock *DoneBB = issetfield || (!isreplacefield && !isboxed) ? nullptr : BasicBlock::Create(jl_LLVMContext, "done_xchg", ctx.f); + BasicBlock *DoneBB = nullptr; 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)); + if (issetfield || (Order == AtomicOrdering::NotAtomic && isswapfield)) { + if (isswapfield) { + auto *load = ctx.builder.CreateAlignedLoad(elty, ptr, Align(alignment)); if (aliasscope) - instr->setMetadata("noalias", aliasscope); + load->setMetadata("noalias", aliasscope); if (tbaa) - tbaa_decorate(tbaa, instr); + tbaa_decorate(tbaa, load); assert(realelty == elty); - if (isreplacefield) { - oldval = mark_julia_type(ctx, instr, isboxed, jltype); - Value *first_ptr = nullptr; - if (maybe_null_if_boxed) - first_ptr = isboxed ? instr : extract_first_ptr(ctx, instr); - Success = emit_nullcheck_guard(ctx, first_ptr, [&] { - return emit_f_is(ctx, oldval, cmp); - }); - BasicBlock *BB = BasicBlock::Create(jl_LLVMContext, "xchg", ctx.f); - ctx.builder.CreateCondBr(Success, BB, DoneBB); - ctx.builder.SetInsertPoint(BB); - } + instr = load; } StoreInst *store = ctx.builder.CreateAlignedStore(r, ptr, Align(alignment)); store->setOrdering(Order); @@ -1632,20 +1640,37 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx, store->setMetadata("noalias", aliasscope); if (tbaa) tbaa_decorate(tbaa, store); - if (DoneBB) - ctx.builder.CreateBr(DoneBB); } - else if (isboxed || isreplacefield) { - // we have to handle isboxed here as a workaround for really bad LLVM design issue: plain Xchg only works with integers + else if (isswapfield && !isboxed) { + // we can't handle isboxed here as a workaround for really bad LLVM + // design issue: plain Xchg only works with integers +#if JL_LLVM_VERSION >= 130000 + auto *store = ctx.builder.CreateAtomicRMW(AtomicRMWInst::Xchg, ptr, r, Align(alignment), Order); +#else + auto *store = ctx.builder.CreateAtomicRMW(AtomicRMWInst::Xchg, ptr, r, Order); + store->setAlignment(Align(alignment)); +#endif + if (aliasscope) + store->setMetadata("noalias", aliasscope); + if (tbaa) + tbaa_decorate(tbaa, store); + instr = store; + } + else { + // replacefield, modifyfield, or swapfield (isboxed && atomic) + DoneBB = BasicBlock::Create(jl_LLVMContext, "done_xchg", ctx.f); bool needloop; PHINode *Succ = nullptr, *Current = nullptr; if (isreplacefield) { - if (!isboxed) { + if (Order == AtomicOrdering::NotAtomic) { + needloop = false; + } + else if (!isboxed) { needloop = ((jl_datatype_t*)jltype)->layout->haspadding; Value *SameType = emit_isa(ctx, cmp, jltype, nullptr).first; if (SameType != ConstantInt::getTrue(jl_LLVMContext)) { BasicBlock *SkipBB = BasicBlock::Create(jl_LLVMContext, "skip_xchg", ctx.f); - BasicBlock *BB = BasicBlock::Create(jl_LLVMContext, "xchg", ctx.f); + BasicBlock *BB = BasicBlock::Create(jl_LLVMContext, "ok_xchg", ctx.f); ctx.builder.CreateCondBr(SameType, BB, SkipBB); ctx.builder.SetInsertPoint(SkipBB); LoadInst *load = ctx.builder.CreateAlignedLoad(elty, ptr, Align(alignment)); @@ -1658,7 +1683,7 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx, ctx.builder.CreateBr(DoneBB); ctx.builder.SetInsertPoint(DoneBB); Succ = ctx.builder.CreatePHI(T_int1, 2); - Succ->addIncoming(ConstantInt::get(T_int1, 0), SkipBB); + Succ->addIncoming(ConstantInt::get(T_int1, false), SkipBB); Current = ctx.builder.CreatePHI(instr->getType(), 2); Current->addIncoming(instr, SkipBB); ctx.builder.SetInsertPoint(BB); @@ -1676,50 +1701,112 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx, needloop = true; } } - else { + else { // swap or modify LoadInst *Current = ctx.builder.CreateAlignedLoad(elty, ptr, Align(alignment)); - Current->setOrdering(AtomicOrdering::Monotonic); + Current->setOrdering(Order == AtomicOrdering::NotAtomic ? Order : AtomicOrdering::Monotonic); if (aliasscope) Current->setMetadata("noalias", aliasscope); if (tbaa) tbaa_decorate(tbaa, Current); Compare = Current; - needloop = true; + needloop = !isswapfield || Order != AtomicOrdering::NotAtomic; } BasicBlock *BB; + PHINode *CmpPhi; if (needloop) { BasicBlock *From = ctx.builder.GetInsertBlock(); BB = BasicBlock::Create(jl_LLVMContext, "xchg", ctx.f); ctx.builder.CreateBr(BB); ctx.builder.SetInsertPoint(BB); - PHINode *Cmp = ctx.builder.CreatePHI(r->getType(), 2); - Cmp->addIncoming(Compare, From); - Compare = Cmp; - } - if (Order == AtomicOrdering::Unordered) - Order = AtomicOrdering::Monotonic; - if (!isreplacefield) - FailOrder = AtomicOrdering::Monotonic; - else if (FailOrder == AtomicOrdering::Unordered) - FailOrder = AtomicOrdering::Monotonic; + CmpPhi = ctx.builder.CreatePHI(elty, 2); + CmpPhi->addIncoming(Compare, From); + Compare = CmpPhi; + } + if (ismodifyfield) { + if (needlock) + emit_lockstate_value(ctx, parent, false); + Value *realCompare = Compare; + if (realelty != elty) + realCompare = ctx.builder.CreateTrunc(realCompare, realelty); + if (intcast) { + ctx.builder.CreateStore(realCompare, ctx.builder.CreateBitCast(intcast, realCompare->getType()->getPointerTo())); + if (maybe_null_if_boxed) + realCompare = ctx.builder.CreateLoad(intcast); + } + if (maybe_null_if_boxed) { + Value *first_ptr = isboxed ? Compare : extract_first_ptr(ctx, Compare); + if (first_ptr) + null_pointer_check(ctx, first_ptr, nullptr); + } + if (intcast) + oldval = mark_julia_slot(intcast, jltype, NULL, tbaa_stack); + else + oldval = mark_julia_type(ctx, realCompare, isboxed, jltype); + rhs = newval(oldval); + if (!isboxed) + r = emit_unbox(ctx, realelty, rhs, jltype); + else + r = boxed(ctx, rhs); + if (realelty != elty) + r = ctx.builder.CreateZExt(r, elty); + if (needlock) + emit_lockstate_value(ctx, parent, true); + cmp = oldval; + } + Value *Done; + if (Order == AtomicOrdering::NotAtomic) { + // modifyfield or replacefield + assert(elty == realelty && !intcast); + auto *load = ctx.builder.CreateAlignedLoad(elty, ptr, Align(alignment)); + if (aliasscope) + load->setMetadata("noalias", aliasscope); + if (tbaa) + tbaa_decorate(tbaa, load); + Value *first_ptr = nullptr; + if (maybe_null_if_boxed && !ismodifyfield) + first_ptr = isboxed ? load : extract_first_ptr(ctx, load); + oldval = mark_julia_type(ctx, load, isboxed, jltype); + Success = emit_nullcheck_guard(ctx, first_ptr, [&] { + return emit_f_is(ctx, oldval, cmp); + }); + if (needloop && ismodifyfield) + CmpPhi->addIncoming(load, ctx.builder.GetInsertBlock()); + assert(Succ == nullptr); + BasicBlock *XchgBB = BasicBlock::Create(jl_LLVMContext, "xchg", ctx.f); + ctx.builder.CreateCondBr(Success, XchgBB, needloop && ismodifyfield ? BB : DoneBB); + ctx.builder.SetInsertPoint(XchgBB); + auto *store = ctx.builder.CreateAlignedStore(r, ptr, Align(alignment)); + if (aliasscope) + store->setMetadata("noalias", aliasscope); + if (tbaa) + tbaa_decorate(tbaa, store); + ctx.builder.CreateBr(DoneBB); + instr = load; + } + else { + if (Order == AtomicOrdering::Unordered) + Order = AtomicOrdering::Monotonic; + if (!isreplacefield) + FailOrder = AtomicOrdering::Monotonic; + else if (FailOrder == AtomicOrdering::Unordered) + FailOrder = AtomicOrdering::Monotonic; #if JL_LLVM_VERSION >= 130000 - auto *store = ctx.builder.CreateAtomicCmpXchg(ptr, Compare, r, Align(alignment), Order, FailOrder); + auto *store = ctx.builder.CreateAtomicCmpXchg(ptr, Compare, r, Align(alignment), Order, FailOrder); #else - auto *store = ctx.builder.CreateAtomicCmpXchg(ptr, Compare, r, Order, FailOrder); - store->setAlignment(Align(alignment)); + auto *store = ctx.builder.CreateAtomicCmpXchg(ptr, Compare, r, Order, FailOrder); + store->setAlignment(Align(alignment)); #endif - if (aliasscope) - store->setMetadata("noalias", aliasscope); - if (tbaa) - tbaa_decorate(tbaa, store); - instr = ctx.builder.Insert(ExtractValueInst::Create(store, 0)); - Success = ctx.builder.Insert(ExtractValueInst::Create(store, 1)); - Value *Done = Success; - if (needloop) { - if (isreplacefield) { + if (aliasscope) + store->setMetadata("noalias", aliasscope); + if (tbaa) + tbaa_decorate(tbaa, store); + instr = ctx.builder.Insert(ExtractValueInst::Create(store, 0)); + Success = ctx.builder.Insert(ExtractValueInst::Create(store, 1)); + Done = Success; + if (isreplacefield && needloop) { Value *realinstr = instr; if (realelty != elty) - realinstr = ctx.builder.CreateTrunc(instr, realelty); + realinstr = ctx.builder.CreateTrunc(realinstr, realelty); if (intcast) { ctx.builder.CreateStore(realinstr, ctx.builder.CreateBitCast(intcast, realinstr->getType()->getPointerTo())); oldval = mark_julia_slot(intcast, jltype, NULL, tbaa_stack); @@ -1739,7 +1826,12 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx, }); Done = ctx.builder.CreateNot(Done); } - cast(Compare)->addIncoming(instr, ctx.builder.GetInsertBlock()); + if (needloop) + ctx.builder.CreateCondBr(Done, DoneBB, BB); + else + ctx.builder.CreateBr(DoneBB); + if (needloop) + CmpPhi->addIncoming(instr, ctx.builder.GetInsertBlock()); } if (Succ != nullptr) { Current->addIncoming(instr, ctx.builder.GetInsertBlock()); @@ -1747,31 +1839,12 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx, Succ->addIncoming(Success, ctx.builder.GetInsertBlock()); Success = Succ; } - if (needloop) - ctx.builder.CreateCondBr(Done, DoneBB, BB); - else - ctx.builder.CreateBr(DoneBB); - } - else { -#if JL_LLVM_VERSION >= 130000 - instr = ctx.builder.CreateAtomicRMW(AtomicRMWInst::Xchg, ptr, r, Align(alignment), Order); -#else - auto *store = ctx.builder.CreateAtomicRMW(AtomicRMWInst::Xchg, ptr, r, Order); - store->setAlignment(Align(alignment)); - instr = store; -#endif - if (aliasscope) - instr->setMetadata("noalias", aliasscope); - if (tbaa) - tbaa_decorate(tbaa, instr); - assert(DoneBB == nullptr); } if (DoneBB) ctx.builder.SetInsertPoint(DoneBB); if (needlock) emit_lockstate_value(ctx, parent, false); if (parent != NULL) { - BasicBlock *DoneBB; if (isreplacefield) { // TOOD: avoid this branch if we aren't making a write barrier BasicBlock *BB = BasicBlock::Create(jl_LLVMContext, "xchg_wb", ctx.f); @@ -1788,7 +1861,12 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx, ctx.builder.SetInsertPoint(DoneBB); } } - if (!issetfield) { + if (ismodifyfield) { + jl_cgval_t argv[2] = { oldval, rhs }; + jl_datatype_t *rettyp = jl_apply_modify_type(jltype); + oldval = emit_new_struct(ctx, (jl_value_t*)rettyp, 2, argv); + } + else if (!issetfield) { // swapfield or replacefield if (realelty != elty) instr = ctx.builder.Insert(CastInst::Create(Instruction::Trunc, instr, realelty)); if (intcast) { @@ -3188,12 +3266,13 @@ static void emit_write_multibarrier(jl_codectx_t &ctx, Value *parent, Value *agg static jl_cgval_t emit_setfield(jl_codectx_t &ctx, jl_datatype_t *sty, const jl_cgval_t &strct, size_t idx0, - const jl_cgval_t &rhs, const jl_cgval_t &cmp, + jl_cgval_t rhs, jl_cgval_t cmp, bool checked, bool wb, AtomicOrdering Order, AtomicOrdering FailOrder, - bool needlock, bool issetfield, bool isreplacefield) + bool needlock, bool issetfield, bool isreplacefield, bool isswapfield, bool ismodifyfield, + const std::string &fname) { if (!sty->name->mutabl && checked) { - std::string msg = "setfield!: immutable struct of type " + std::string msg = fname + "immutable struct of type " + std::string(jl_symbol_name(sty->name->name)) + " cannot be changed"; emit_error(ctx, msg); @@ -3217,29 +3296,48 @@ static jl_cgval_t emit_setfield(jl_codectx_t &ctx, jl_cgval_t rhs_union = convert_julia_type(ctx, rhs, jfty); if (rhs_union.typ == jl_bottom_type) return jl_cgval_t(); - Value *tindex = compute_tindex_unboxed(ctx, rhs_union, jfty); - tindex = ctx.builder.CreateNUWSub(tindex, ConstantInt::get(T_int8, 1)); Value *ptindex = ctx.builder.CreateInBoundsGEP(T_int8, emit_bitcast(ctx, maybe_decay_tracked(ctx, addr), T_pint8), ConstantInt::get(T_size, fsz)); if (needlock) emit_lockstate_value(ctx, strct, true); + BasicBlock *BB = ctx.builder.GetInsertBlock(); jl_cgval_t oldval = rhs; if (!issetfield) oldval = emit_unionload(ctx, addr, ptindex, jfty, fsz, al, strct.tbaa, true); Value *Success; BasicBlock *DoneBB; - if (isreplacefield) { - BasicBlock *BB = BasicBlock::Create(jl_LLVMContext, "xchg", ctx.f); + if (isreplacefield || ismodifyfield) { + if (ismodifyfield) { + if (needlock) + emit_lockstate_value(ctx, strct, false); + jl_cgval_t argv[3] = { cmp, oldval, rhs }; + Value *callval = emit_jlcall(ctx, jlapplygeneric_func, nullptr, argv, 3, JLCALL_F_CC); + rhs = mark_julia_type(ctx, callval, true, jl_any_type); + if (!jl_subtype(rhs.typ, jfty)) { + emit_typecheck(ctx, rhs, jfty, fname); + rhs = update_julia_type(ctx, rhs, jfty); + } + rhs_union = convert_julia_type(ctx, rhs, jfty); + if (rhs_union.typ == jl_bottom_type) + return jl_cgval_t(); + if (needlock) + emit_lockstate_value(ctx, strct, true); + cmp = oldval; + oldval = emit_unionload(ctx, addr, ptindex, jfty, fsz, al, strct.tbaa, true); + } + BasicBlock *XchgBB = BasicBlock::Create(jl_LLVMContext, "xchg", ctx.f); DoneBB = BasicBlock::Create(jl_LLVMContext, "done_xchg", ctx.f); Success = emit_f_is(ctx, oldval, cmp); - ctx.builder.CreateCondBr(Success, BB, DoneBB); - ctx.builder.SetInsertPoint(BB); + ctx.builder.CreateCondBr(Success, XchgBB, ismodifyfield ? BB : DoneBB); + ctx.builder.SetInsertPoint(XchgBB); } + Value *tindex = compute_tindex_unboxed(ctx, rhs_union, jfty); + tindex = ctx.builder.CreateNUWSub(tindex, ConstantInt::get(T_int8, 1)); tbaa_decorate(tbaa_unionselbyte, ctx.builder.CreateAlignedStore(tindex, ptindex, Align(1))); // copy data if (!rhs.isghost) { emit_unionmove(ctx, addr, strct.tbaa, rhs, nullptr); } - if (isreplacefield) { + if (isreplacefield || ismodifyfield) { ctx.builder.CreateBr(DoneBB); ctx.builder.SetInsertPoint(DoneBB); } @@ -3251,6 +3349,11 @@ static jl_cgval_t emit_setfield(jl_codectx_t &ctx, jl_datatype_t *rettyp = jl_apply_cmpswap_type(jfty); oldval = emit_new_struct(ctx, (jl_value_t*)rettyp, 2, argv); } + else if (ismodifyfield) { + jl_cgval_t argv[2] = {oldval, rhs}; + jl_datatype_t *rettyp = jl_apply_modify_type(jfty); + oldval = emit_new_struct(ctx, (jl_value_t*)rettyp, 2, argv); + } return oldval; } else { @@ -3261,7 +3364,7 @@ static jl_cgval_t emit_setfield(jl_codectx_t &ctx, return typed_store(ctx, addr, NULL, rhs, cmp, jfty, strct.tbaa, nullptr, wb ? maybe_bitcast(ctx, data_pointer(ctx, strct), T_pjlvalue) : nullptr, isboxed, Order, FailOrder, align, - needlock, issetfield, isreplacefield, maybe_null); + needlock, issetfield, isreplacefield, isswapfield, ismodifyfield, maybe_null, fname); } } @@ -3440,7 +3543,7 @@ static jl_cgval_t emit_new_struct(jl_codectx_t &ctx, jl_value_t *ty, size_t narg else need_wb = false; emit_typecheck(ctx, rhs, jl_svecref(sty->types, i), "new"); - emit_setfield(ctx, sty, strctinfo, i, rhs, jl_cgval_t(), false, need_wb, AtomicOrdering::NotAtomic, AtomicOrdering::NotAtomic, false, true, false); + emit_setfield(ctx, sty, strctinfo, i, rhs, jl_cgval_t(), false, need_wb, AtomicOrdering::NotAtomic, AtomicOrdering::NotAtomic, false, true, false, false, false, ""); } return strctinfo; } diff --git a/src/codegen.cpp b/src/codegen.cpp index 3292df745d90b4..246534491151a9 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -3005,7 +3005,10 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, false, true, false, - false); + false, + false, + false, + ""); } } *ret = ary; @@ -3147,18 +3150,21 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, else if ((f == jl_builtin_setfield && (nargs == 3 || nargs == 4)) || (f == jl_builtin_swapfield && (nargs == 3 || nargs == 4)) || - (f == jl_builtin_replacefield && (nargs == 4 || nargs == 5 || nargs == 6))) { + (f == jl_builtin_replacefield && (nargs == 4 || nargs == 5 || nargs == 6)) || + (true && f == jl_builtin_modifyfield && (nargs == 4 || nargs == 5))) { bool issetfield = f == jl_builtin_setfield; bool isreplacefield = f == jl_builtin_replacefield; + bool isswapfield = f == jl_builtin_swapfield; + bool ismodifyfield = f == jl_builtin_modifyfield; const jl_cgval_t undefval; const jl_cgval_t &obj = argv[1]; const jl_cgval_t &fld = argv[2]; - jl_cgval_t val = argv[isreplacefield ? 4 : 3]; - const jl_cgval_t &cmp = isreplacefield ? argv[3] : undefval; + jl_cgval_t val = argv[isreplacefield || ismodifyfield ? 4 : 3]; + const jl_cgval_t &cmp = isreplacefield || ismodifyfield ? 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]; + const std::string fname = issetfield ? "setfield!" : isreplacefield ? "replacefield!" : isswapfield ? "swapfield!" : "modifyfield!"; + if (nargs >= (isreplacefield || ismodifyfield ? 5 : 4)) { + const jl_cgval_t &ord = argv[isreplacefield || ismodifyfield ? 5 : 4]; emit_typecheck(ctx, ord, (jl_value_t*)jl_symbol_type, fname); if (!ord.constant) return false; @@ -3192,7 +3198,7 @@ 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)) { - if (!jl_subtype(val.typ, ft)) { + if (!ismodifyfield && !jl_subtype(val.typ, ft)) { emit_typecheck(ctx, val, ft, fname); val = update_julia_type(ctx, val, ft); } @@ -3208,8 +3214,11 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, isreplacefield ? (isatomic ? "replacefield!: atomic field cannot be written non-atomically" : "replacefield!: non-atomic field cannot be written atomically") : + isswapfield ? (isatomic ? "swapfield!: atomic field cannot be written non-atomically" - : "swapfield!: non-atomic field cannot be written atomically")); + : "swapfield!: non-atomic field cannot be written atomically") : + (isatomic ? "modifyfield!: atomic field cannot be written non-atomically" + : "modifyfield!: non-atomic field cannot be written atomically")); *ret = jl_cgval_t(); return true; } @@ -3227,7 +3236,8 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, (needlock || fail_order <= jl_memory_order_notatomic) ? (isboxed ? AtomicOrdering::Unordered : AtomicOrdering::NotAtomic) // TODO: we should do this for anything with CountTrackedPointers(elty).count > 0 : get_llvm_atomic_order(fail_order), - needlock, issetfield, isreplacefield); + needlock, issetfield, isreplacefield, isswapfield, ismodifyfield, + fname); return true; } } diff --git a/src/intrinsics.cpp b/src/intrinsics.cpp index e1d821a34e42dd..7883542c74a130 100644 --- a/src/intrinsics.cpp +++ b/src/intrinsics.cpp @@ -684,7 +684,7 @@ static jl_cgval_t emit_pointerset(jl_codectx_t &ctx, jl_cgval_t *argv) if (!type_is_ghost(ptrty)) { thePtr = emit_unbox(ctx, ptrty->getPointerTo(), e, e.typ); typed_store(ctx, thePtr, im1, x, jl_cgval_t(), ety, tbaa_data, nullptr, nullptr, isboxed, - AtomicOrdering::NotAtomic, AtomicOrdering::NotAtomic, align_nb, false, true, false, false); + AtomicOrdering::NotAtomic, AtomicOrdering::NotAtomic, align_nb, false, true, false, false, false, false, ""); } } return e; @@ -778,15 +778,18 @@ static jl_cgval_t emit_atomic_pointerref(jl_codectx_t &ctx, jl_cgval_t *argv) // 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) +// x(e[i], y) (modify) +static jl_cgval_t emit_atomic_pointerop(jl_codectx_t &ctx, intrinsic f, const jl_cgval_t *argv, int nargs) { bool issetfield = f == atomic_pointerset; bool isreplacefield = f == atomic_pointerreplace; + bool isswapfield = f == atomic_pointerswap; + bool ismodifyfield = f == atomic_pointermodify; 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 &x = isreplacefield || ismodifyfield ? argv[2] : argv[1]; + const jl_cgval_t &y = isreplacefield || ismodifyfield ? argv[1] : undefval; + const jl_cgval_t &ord = isreplacefield || ismodifyfield ? argv[3] : argv[2]; const jl_cgval_t &failord = isreplacefield ? argv[4] : undefval; jl_value_t *aty = e.typ; @@ -814,7 +817,7 @@ static jl_cgval_t emit_atomic_pointerset(jl_codectx_t &ctx, intrinsic f, const j 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); + llvm_order, llvm_failorder, sizeof(jl_value_t*), false, issetfield, isreplacefield, isswapfield, ismodifyfield, false, "atomic_pointermodify"); if (issetfield) ret = e; return ret; @@ -826,7 +829,8 @@ static jl_cgval_t emit_atomic_pointerset(jl_codectx_t &ctx, intrinsic f, const j emit_error(ctx, msg); return jl_cgval_t(); } - emit_typecheck(ctx, x, ety, std::string(jl_intrinsic_name((int)f))); + if (!ismodifyfield) + 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) { @@ -847,7 +851,7 @@ static jl_cgval_t emit_atomic_pointerset(jl_codectx_t &ctx, intrinsic f, const j 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); + llvm_order, llvm_failorder, nb, false, issetfield, isreplacefield, isswapfield, ismodifyfield, false, "atomic_pointermodify"); if (issetfield) ret = e; return ret; @@ -1087,10 +1091,9 @@ static jl_cgval_t emit_intrinsic(jl_codectx_t &ctx, intrinsic f, jl_value_t **ar return emit_atomic_pointerref(ctx, argv); case atomic_pointerset: case atomic_pointerswap: - case atomic_pointerreplace: - return emit_atomic_pointerset(ctx, f, argv, nargs); case atomic_pointermodify: - return emit_runtime_call(ctx, f, argv, nargs); + case atomic_pointerreplace: + return emit_atomic_pointerop(ctx, f, argv, nargs); case bitcast: return generic_bitcast(ctx, argv); case trunc_int: diff --git a/src/runtime_intrinsics.c b/src/runtime_intrinsics.c index be78be74172cbc..741bb5448b847d 100644 --- a/src/runtime_intrinsics.c +++ b/src/runtime_intrinsics.c @@ -142,15 +142,25 @@ JL_DLLEXPORT jl_value_t *jl_atomic_pointerswap(jl_value_t *p, jl_value_t *x, jl_ return y; } -JL_DLLEXPORT jl_value_t *jl_atomic_pointermodify(jl_value_t *p, jl_value_t *f, jl_value_t *x, jl_value_t *order_sym) +JL_DLLEXPORT jl_value_t *jl_atomic_pointermodify(jl_value_t *p, jl_value_t *f, jl_value_t *x, jl_value_t *order) { - // n.b. we use seq_cst always here, but need to verify the order sym - // against the weaker load-only that happens first - if (order_sym == (jl_value_t*)acquire_release_sym) - order_sym = (jl_value_t*)acquire_sym; - jl_value_t *expected = jl_atomic_pointerref(p, order_sym); + JL_TYPECHK(atomic_pointerref, pointer, p); + JL_TYPECHK(atomic_pointerref, symbol, order) + (void)jl_get_atomic_order_checked((jl_sym_t*)order, 1, 1); jl_value_t *ety = jl_tparam0(jl_typeof(p)); char *pp = (char*)jl_unbox_long(p); + jl_value_t *expected; + if (ety == (jl_value_t*)jl_any_type) { + expected = jl_atomic_load((jl_value_t**)pp); + } + else { + if (!is_valid_intrinsic_elptr(ety)) + jl_error("atomic_pointermodify: invalid pointer"); + size_t nb = jl_datatype_size(ety); + if ((nb & (nb - 1)) != 0 || nb > MAX_POINTERATOMIC_SIZE) + jl_error("atomic_pointermodify: invalid pointer for atomic operation"); + expected = jl_atomic_new_bits(ety, pp); + } jl_value_t **args; JL_GC_PUSHARGS(args, 2); args[0] = expected; diff --git a/test/intrinsics.jl b/test/intrinsics.jl index 7fb6bd651ebc09..589590cf78d14e 100644 --- a/test/intrinsics.jl +++ b/test/intrinsics.jl @@ -191,8 +191,8 @@ for TT in (Int8, Int16, Int32, Int64, Int128, Int256, Int512, Complex{Int32}, Co @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_pointermodify: invalid pointer for atomic operation") Core.Intrinsics.atomic_pointermodify(p, add, T(1), :sequentially_consistent) + @test_throws ErrorException("atomic_pointermodify: 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[]