From b8cd73082966c1ace146a94c3447725fa2ee0468 Mon Sep 17 00:00:00 2001 From: Juan Ignacio Polanco Date: Wed, 23 Feb 2022 21:07:30 +0100 Subject: [PATCH 01/46] Make sure `range(start; step, length)` uses TwicePrecision when possible, fixes #44292. (#44313) (cherry picked from commit 1b47efb08753a808c4869bb4fe0561e526cde612) --- base/twiceprecision.jl | 12 ++++++++++-- test/ranges.jl | 12 ++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/base/twiceprecision.jl b/base/twiceprecision.jl index 8f80b2c8438a0..6d91431e47abb 100644 --- a/base/twiceprecision.jl +++ b/base/twiceprecision.jl @@ -408,7 +408,7 @@ function floatrange(a::AbstractFloat, st::AbstractFloat, len::Real, divisor::Abs steprangelen_hp(T, (a,divisor), (st,divisor), nbitslen(T, len, 1), len, oneunit(len)) end -function (:)(start::T, step::T, stop::T) where T<:Union{Float16,Float32,Float64} +function (:)(start::T, step::T, stop::T) where T<:IEEEFloat step == 0 && throw(ArgumentError("range step cannot be zero")) # see if the inputs have exact rational approximations (and if so, # perform all computations in terms of the rationals) @@ -453,7 +453,10 @@ end step(r::StepRangeLen{T,TwicePrecision{T},TwicePrecision{T}}) where {T<:AbstractFloat} = T(r.step) step(r::StepRangeLen{T,TwicePrecision{T},TwicePrecision{T}}) where {T} = T(r.step) -function range_start_step_length(a::T, st::T, len::Integer) where T<:Union{Float16,Float32,Float64} +range_start_step_length(a, st::IEEEFloat, len::Integer) = + range_start_step_length(oftype(st, a), st, len) + +function range_start_step_length(a::T, st::T, len::Integer) where T<:IEEEFloat len = len + 0 # promote with Int start_n, start_d = rat(a) step_n, step_d = rat(st) @@ -471,6 +474,11 @@ function range_start_step_length(a::T, st::T, len::Integer) where T<:Union{Float steprangelen_hp(T, a, st, 0, len, 1) end +function range_step_stop_length(step::IEEEFloat, stop, len::Integer) + r = range_start_step_length(stop, negate(step), len) + reverse(r) +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 diff --git a/test/ranges.jl b/test/ranges.jl index a7f26c7efa629..536c1f4710d9d 100644 --- a/test/ranges.jl +++ b/test/ranges.jl @@ -1612,6 +1612,18 @@ end @test x isa StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}} end +@testset "Issue #44292" begin + let x = @inferred range(0, step=0.2, length=5) + @test x isa StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}} + @test x == [0.0, 0.2, 0.4, 0.6, 0.8] + end + + let x = @inferred range(stop=1, step=0.2, length=5) + @test x isa StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}} + @test x == [0.2, 0.4, 0.6, 0.8, 1.0] + end +end + @testset "Views of ranges" begin @test view(Base.OneTo(10), Base.OneTo(5)) === Base.OneTo(5) @test view(1:10, 1:5) === 1:5 From b2a206183cba1072a0944af494a4b4de633f79bf Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Thu, 24 Feb 2022 01:30:09 -0600 Subject: [PATCH 02/46] Cache external CodeInstances (#43990) Prior to this PR, Julia's precompiled `*.ji` files saved just two categories of code: unspecialized method definitions and type-specialized code for the methods defined by the package. Any novel specializations of methods from Base or previously-loaded packages were not saved, and therefore effectively thrown away. This PR caches all the code---internal or external---called during package definition that hadn't been previously inferred, as long as there is a backedge linking it back to a method owned by a module being precompiled. (The latter condition ensures it will actually be called by package methods, and not merely transiently generated for the purpose of, e.g., metaprogramming or variable initialization.) This makes precompilation more intuitive (now it saves all relevant inference results), and substantially reduces latency for inference-bound packages. Closes #42016 Fixes #35972 Issue #35972 arose because codegen got started without re-inferring some discarded CodeInstances. This forced the compiler to insert a `jl_invoke`. This PR fixes the issue because needed CodeInstances are no longer discarded by precompilation. (cherry picked from commit df81bf9a96c59f257a01307cd0ecf05035d8301f) --- base/Base.jl | 19 +- base/binaryplatforms.jl | 61 +++-- base/compiler/typeinfer.jl | 10 + base/loading.jl | 8 +- src/codegen.cpp | 2 +- src/dump.c | 390 +++++++++++++++++++++++++++--- src/gf.c | 36 ++- src/jltypes.c | 8 +- src/julia.h | 2 + src/julia_internal.h | 4 + src/method.c | 50 +++- stdlib/Artifacts/src/Artifacts.jl | 17 +- test/precompile.jl | 213 +++++++++++++++- 13 files changed, 724 insertions(+), 96 deletions(-) diff --git a/base/Base.jl b/base/Base.jl index 9ad0cdf7a6661..a3fe44a2add86 100644 --- a/base/Base.jl +++ b/base/Base.jl @@ -427,7 +427,7 @@ end_base_include = time_ns() const _sysimage_modules = PkgId[] in_sysimage(pkgid::PkgId) = pkgid in _sysimage_modules -# Precompiles for Revise +# Precompiles for Revise and other packages # TODO: move these to contrib/generate_precompile.jl # The problem is they don't work there for match = _methods(+, (Int, Int), -1, get_world_counter()) @@ -461,6 +461,23 @@ for match = _methods(+, (Int, Int), -1, get_world_counter()) # Code loading uses this sortperm(mtime.(readdir(".")), rev=true) + # JLLWrappers uses these + Dict{UUID,Set{String}}()[UUID("692b3bcd-3c85-4b1f-b108-f13ce0eb3210")] = Set{String}() + get!(Set{String}, Dict{UUID,Set{String}}(), UUID("692b3bcd-3c85-4b1f-b108-f13ce0eb3210")) + eachindex(IndexLinear(), Expr[]) + push!(Expr[], Expr(:return, false)) + vcat(String[], String[]) + k, v = (:hello => nothing) + precompile(indexed_iterate, (Pair{Symbol, Union{Nothing, String}}, Int)) + precompile(indexed_iterate, (Pair{Symbol, Union{Nothing, String}}, Int, Int)) + # Preferences uses these + precompile(get_preferences, (UUID,)) + precompile(record_compiletime_preference, (UUID, String)) + get(Dict{String,Any}(), "missing", nothing) + delete!(Dict{String,Any}(), "missing") + for (k, v) in Dict{String,Any}() + println(k) + end break # only actually need to do this once end diff --git a/base/binaryplatforms.jl b/base/binaryplatforms.jl index 61e1af796999d..87c7f029f0563 100644 --- a/base/binaryplatforms.jl +++ b/base/binaryplatforms.jl @@ -40,10 +40,10 @@ struct Platform <: AbstractPlatform # The "compare strategy" allows selective overriding on how a tag is compared compare_strategies::Dict{String,Function} - function Platform(arch::String, os::String; + # Passing `tags` as a `Dict` avoids the need to infer different NamedTuple specializations + function Platform(arch::String, os::String, _tags::Dict{String}; validate_strict::Bool = false, - compare_strategies::Dict{String,<:Function} = Dict{String,Function}(), - kwargs...) + compare_strategies::Dict{String,<:Function} = Dict{String,Function}()) # A wee bit of normalization os = lowercase(os) arch = CPUID.normalize_arch(arch) @@ -52,8 +52,9 @@ struct Platform <: AbstractPlatform "arch" => arch, "os" => os, ) - for (tag, value) in kwargs - tag = lowercase(string(tag::Symbol)) + for (tag, value) in _tags + value = value::Union{String,VersionNumber,Nothing} + tag = lowercase(tag) if tag ∈ ("arch", "os") throw(ArgumentError("Cannot double-pass key $(tag)")) end @@ -70,8 +71,8 @@ struct Platform <: AbstractPlatform if tag ∈ ("libgfortran_version", "libstdcxx_version", "os_version") if isa(value, VersionNumber) value = string(value) - elseif isa(value, AbstractString) - v = tryparse(VersionNumber, String(value)::String) + elseif isa(value, String) + v = tryparse(VersionNumber, value) if isa(v, VersionNumber) value = string(v) end @@ -110,6 +111,19 @@ struct Platform <: AbstractPlatform end end +# Keyword interface (to avoid inference of specialized NamedTuple methods, use the Dict interface for `tags`) +function Platform(arch::String, os::String; + validate_strict::Bool = false, + compare_strategies::Dict{String,<:Function} = Dict{String,Function}(), + kwargs...) + tags = Dict{String,Any}(String(tag)::String=>tagvalue(value) for (tag, value) in kwargs) + return Platform(arch, os, tags; validate_strict, compare_strategies) +end + +tagvalue(v::Union{String,VersionNumber,Nothing}) = v +tagvalue(v::Symbol) = String(v) +tagvalue(v::AbstractString) = convert(String, v)::String + # Simple tag insertion that performs a little bit of validation function add_tag!(tags::Dict{String,String}, tag::String, value::String) # I know we said only alphanumeric and dots, but let's be generous so that we can expand @@ -699,21 +713,22 @@ function Base.parse(::Type{Platform}, triplet::AbstractString; validate_strict:: end # Extract the information we're interested in: + tags = Dict{String,Any}() arch = get_field(m, arch_mapping) os = get_field(m, os_mapping) - libc = get_field(m, libc_mapping) - call_abi = get_field(m, call_abi_mapping) - libgfortran_version = get_field(m, libgfortran_version_mapping) - libstdcxx_version = get_field(m, libstdcxx_version_mapping) - cxxstring_abi = get_field(m, cxxstring_abi_mapping) + tags["libc"] = get_field(m, libc_mapping) + tags["call_abi"] = get_field(m, call_abi_mapping) + tags["libgfortran_version"] = get_field(m, libgfortran_version_mapping) + tags["libstdcxx_version"] = get_field(m, libstdcxx_version_mapping) + tags["cxxstring_abi"] = get_field(m, cxxstring_abi_mapping) function split_tags(tagstr) tag_fields = split(tagstr, "-"; keepempty=false) if isempty(tag_fields) return Pair{String,String}[] end - return map(v -> Symbol(v[1]) => v[2], split.(tag_fields, "+")) + return map(v -> String(v[1]) => String(v[2]), split.(tag_fields, "+")) end - tags = split_tags(m["tags"]) + merge!(tags, Dict(split_tags(m["tags"]))) # Special parsing of os version number, if any exists function extract_os_version(os_name, pattern) @@ -730,18 +745,9 @@ function Base.parse(::Type{Platform}, triplet::AbstractString; validate_strict:: if os == "freebsd" os_version = extract_os_version("freebsd", r".*freebsd([\d.]+)") end + tags["os_version"] = os_version - return Platform( - arch, os; - validate_strict, - libc, - call_abi, - libgfortran_version, - cxxstring_abi, - libstdcxx_version, - os_version, - tags..., - ) + return Platform(arch, os, tags; validate_strict) end throw(ArgumentError("Platform `$(triplet)` is not an officially supported platform")) end @@ -1068,4 +1074,9 @@ function select_platform(download_info::Dict, platform::AbstractPlatform = HostP return download_info[p] end +# precompiles to reduce latency (see https://github.com/JuliaLang/julia/pull/43990#issuecomment-1025692379) +Dict{Platform,String}()[HostPlatform()] = "" +Platform("x86_64", "linux", Dict{String,Any}(); validate_strict=true) +Platform("x86_64", "linux", Dict{String,String}(); validate_strict=false) # called this way from Artifacts.unpack_platform + end # module diff --git a/base/compiler/typeinfer.jl b/base/compiler/typeinfer.jl index d600df1dbb0a1..4015b7c00bf0d 100644 --- a/base/compiler/typeinfer.jl +++ b/base/compiler/typeinfer.jl @@ -1,5 +1,9 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +# Tracking of newly-inferred MethodInstances during precompilation +const track_newly_inferred = RefValue{Bool}(false) +const newly_inferred = MethodInstance[] + # build (and start inferring) the inference frame for the top-level MethodInstance function typeinf(interp::AbstractInterpreter, result::InferenceResult, cache::Symbol) frame = InferenceState(result, cache, interp) @@ -389,6 +393,12 @@ function cache_result!(interp::AbstractInterpreter, result::InferenceResult) if !already_inferred inferred_result = transform_result_for_cache(interp, linfo, valid_worlds, result.src) code_cache(interp)[linfo] = CodeInstance(result, inferred_result, valid_worlds) + if track_newly_inferred[] + m = linfo.def + if isa(m, Method) + m.module != Core && push!(newly_inferred, linfo) + end + end end unlock_mi_inference(interp, linfo) nothing diff --git a/base/loading.jl b/base/loading.jl index 7dce4532c1571..1f3297df36448 100644 --- a/base/loading.jl +++ b/base/loading.jl @@ -1395,13 +1395,17 @@ function include_package_for_output(pkg::PkgId, input::String, depot_path::Vecto task_local_storage()[:SOURCE_PATH] = source end + Core.Compiler.track_newly_inferred.x = true try Base.include(Base.__toplevel__, input) catch ex precompilableerror(ex) || rethrow() @debug "Aborting `create_expr_cache'" exception=(ErrorException("Declaration of __precompile__(false) not allowed"), catch_backtrace()) exit(125) # we define status = 125 means PrecompileableError + finally + Core.Compiler.track_newly_inferred.x = false end + ccall(:jl_set_newly_inferred, Cvoid, (Any,), Core.Compiler.newly_inferred) end const PRECOMPILE_TRACE_COMPILE = Ref{String}() @@ -2033,12 +2037,12 @@ end Compile the given function `f` for the argument tuple (of types) `args`, but do not execute it. """ -function precompile(@nospecialize(f), args::Tuple) +function precompile(@nospecialize(f), @nospecialize(args::Tuple)) precompile(Tuple{Core.Typeof(f), args...}) end const ENABLE_PRECOMPILE_WARNINGS = Ref(false) -function precompile(argt::Type) +function precompile(@nospecialize(argt::Type)) ret = ccall(:jl_compile_hint, Int32, (Any,), argt) != 0 if !ret && ENABLE_PRECOMPILE_WARNINGS[] @warn "Inactive precompile statement" maxlog=100 form=argt _module=nothing _file=nothing _line=0 diff --git a/src/codegen.cpp b/src/codegen.cpp index be6d8e2f66325..c9e7b2280777e 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -7849,7 +7849,7 @@ jl_compile_result_t jl_emit_codeinst( // don't delete inlineable code, unless it is constant (codeinst->invoke == jl_fptr_const_return_addr || !jl_ir_flag_inlineable((jl_array_t*)codeinst->inferred)) && // don't delete code when generating a precompile file - !imaging_mode) { + !(imaging_mode || jl_options.incremental)) { // if not inlineable, code won't be needed again codeinst->inferred = jl_nothing; } diff --git a/src/dump.c b/src/dump.c index f2c8629ca9c8b..919bac8c82a07 100644 --- a/src/dump.c +++ b/src/dump.c @@ -92,6 +92,16 @@ static arraylist_t reinit_list; // This is not quite globally rooted, but we take care to only // ever assigned rooted values here. static jl_array_t *serializer_worklist JL_GLOBALLY_ROOTED; +// external MethodInstances we want to serialize +static htable_t external_mis; +// Inference tracks newly-inferred MethodInstances during precompilation +// and registers them by calling jl_set_newly_inferred +static jl_array_t *newly_inferred JL_GLOBALLY_ROOTED; + +// New roots to add to Methods. These can't be added until after +// recaching is complete, so we have to hold on to them separately +// Stored as method => (worklist_key, roots) +static htable_t queued_method_roots; // inverse of backedges graph (caller=>callees hash) htable_t edges_map; @@ -140,6 +150,18 @@ jl_value_t *jl_deser_symbol(uint8_t tag) return deser_symbols[tag]; } +uint64_t jl_worklist_key(jl_array_t *worklist) +{ + assert(jl_is_array(worklist)); + size_t len = jl_array_len(worklist); + if (len > 0) { + jl_module_t *topmod = (jl_module_t*)jl_array_ptr_ref(worklist, len-1); + assert(jl_is_module(topmod)); + return topmod->build_id; + } + return 0; +} + // --- serialize --- #define jl_serialize_value(s, v) jl_serialize_value_((s), (jl_value_t*)(v), 0) @@ -163,6 +185,11 @@ static int module_in_worklist(jl_module_t *mod) JL_NOTSAFEPOINT return 0; } +static int method_instance_in_queue(jl_method_instance_t *mi) +{ + return ptrhash_get(&external_mis, mi) != HT_NOTFOUND; +} + // compute whether a type references something internal to worklist // and thus could not have existed before deserialize // and thus does not need delayed unique-ing @@ -219,6 +246,75 @@ static int type_recursively_external(jl_datatype_t *dt) JL_NOTSAFEPOINT return 1; } +// When we infer external method instances, ensure they link back to the +// package. Otherwise they might be, e.g., for external macros +static int has_backedge_to_worklist(jl_method_instance_t *mi, htable_t *visited) +{ + void **bp = ptrhash_bp(visited, mi); + // HT_NOTFOUND: not yet analyzed + // HT_NOTFOUND + 1: doesn't link back + // HT_NOTFOUND + 2: does link back + if (*bp != HT_NOTFOUND) + return (char*)*bp - (char*)HT_NOTFOUND - 1; + *bp = (void*)((char*)HT_NOTFOUND + 1); // preliminarily mark as "not found" + jl_module_t *mod = mi->def.module; + if (jl_is_method(mod)) + mod = ((jl_method_t*)mod)->module; + assert(jl_is_module(mod)); + if (mi->precompiled || module_in_worklist(mod)) { + *bp = (void*)((char*)HT_NOTFOUND + 2); // found + return 1; + } + if (!mi->backedges) { + return 0; + } + size_t i, n = jl_array_len(mi->backedges); + for (i = 0; i < n; i++) { + jl_method_instance_t *be = (jl_method_instance_t*)jl_array_ptr_ref(mi->backedges, i); + if (has_backedge_to_worklist(be, visited)) { + *bp = (void*)((char*)HT_NOTFOUND + 2); // found + return 1; + } + } + return 0; +} + +// given the list of MethodInstances that were inferred during the +// build, select those that are external and have at least one +// relocatable CodeInstance. +static size_t queue_external_mis(jl_array_t *list) +{ + size_t i, n = 0; + htable_t visited; + htable_new(&visited, 0); + if (list) { + assert(jl_is_array(list)); + size_t n0 = jl_array_len(list); + for (i = 0; i < n0; i++) { + jl_method_instance_t *mi = (jl_method_instance_t*)jl_array_ptr_ref(list, i); + assert(jl_is_method_instance(mi)); + if (jl_is_method(mi->def.value)) { + jl_method_t *m = mi->def.method; + if (!module_in_worklist(m->module)) { + jl_code_instance_t *ci = mi->cache; + int relocatable = 0; + while (ci) { + relocatable |= ci->relocatability; + ci = ci->next; + } + if (relocatable && ptrhash_get(&external_mis, mi) == HT_NOTFOUND) { + if (has_backedge_to_worklist(mi, &visited)) { + ptrhash_put(&external_mis, mi, mi); + n++; + } + } + } + } + } + } + htable_free(&visited); + return n; +} static void jl_serialize_datatype(jl_serializer_state *s, jl_datatype_t *dt) JL_GC_DISABLED { @@ -485,8 +581,12 @@ static int jl_serialize_generic(jl_serializer_state *s, jl_value_t *v) JL_GC_DIS return 0; } -static void jl_serialize_code_instance(jl_serializer_state *s, jl_code_instance_t *codeinst, int skip_partial_opaque) JL_GC_DISABLED +static void jl_serialize_code_instance(jl_serializer_state *s, jl_code_instance_t *codeinst, int skip_partial_opaque, int internal) JL_GC_DISABLED { + if (internal > 2) { + while (codeinst && !codeinst->relocatability) + codeinst = codeinst->next; + } if (jl_serialize_generic(s, (jl_value_t*)codeinst)) { return; } @@ -507,7 +607,7 @@ static void jl_serialize_code_instance(jl_serializer_state *s, jl_code_instance_ if (write_ret_type && codeinst->rettype_const && jl_typeis(codeinst->rettype_const, jl_partial_opaque_type)) { if (skip_partial_opaque) { - jl_serialize_code_instance(s, codeinst->next, skip_partial_opaque); + jl_serialize_code_instance(s, codeinst->next, skip_partial_opaque, internal); return; } else { @@ -534,12 +634,13 @@ static void jl_serialize_code_instance(jl_serializer_state *s, jl_code_instance_ jl_serialize_value(s, jl_nothing); } write_uint8(s->s, codeinst->relocatability); - jl_serialize_code_instance(s, codeinst->next, skip_partial_opaque); + jl_serialize_code_instance(s, codeinst->next, skip_partial_opaque, internal); } enum METHOD_SERIALIZATION_MODE { METHOD_INTERNAL = 1, METHOD_EXTERNAL_MT = 2, + METHOD_HAS_NEW_ROOTS = 4, }; static void jl_serialize_value_(jl_serializer_state *s, jl_value_t *v, int as_literal) JL_GC_DISABLED @@ -665,9 +766,16 @@ static void jl_serialize_value_(jl_serializer_state *s, jl_value_t *v, int as_li else if (jl_is_method(v)) { write_uint8(s->s, TAG_METHOD); jl_method_t *m = (jl_method_t*)v; - int serialization_mode = 0; + uint64_t key = 0; + int serialization_mode = 0, nwithkey = 0; if (m->is_for_opaque_closure || module_in_worklist(m->module)) serialization_mode |= METHOD_INTERNAL; + if (!(serialization_mode & METHOD_INTERNAL)) { + key = jl_worklist_key(serializer_worklist); + nwithkey = nroots_with_key(m, key); + if (nwithkey > 0) + serialization_mode |= METHOD_HAS_NEW_ROOTS; + } if (!(serialization_mode & METHOD_INTERNAL)) { // flag this in the backref table as special uintptr_t *bp = (uintptr_t*)ptrhash_bp(&backref_table, v); @@ -693,8 +801,25 @@ static void jl_serialize_value_(jl_serializer_state *s, jl_value_t *v, int as_li else { jl_serialize_value(s, (jl_value_t*)m->external_mt); } - if (!(serialization_mode & METHOD_INTERNAL)) + if (!(serialization_mode & METHOD_INTERNAL)) { + if (serialization_mode & METHOD_HAS_NEW_ROOTS) { + // Serialize the roots that belong to key + write_uint64(s->s, key); + write_int32(s->s, nwithkey); + rle_iter_state rootiter = rle_iter_init(0); + uint64_t *rletable = NULL; + size_t nblocks2 = 0, nroots = jl_array_len(m->roots); + if (m->root_blocks) { + rletable = (uint64_t*)jl_array_data(m->root_blocks); + nblocks2 = jl_array_len(m->root_blocks); + } + // this visits every item, if it becomes a bottlneck we could hop blocks + while (rle_iter_increment(&rootiter, nroots, rletable, nblocks2)) + if (rootiter.key == key) + jl_serialize_value(s, jl_array_ptr_ref(m->roots, rootiter.i)); + } return; + } jl_serialize_value(s, m->specializations); jl_serialize_value(s, jl_atomic_load_relaxed(&m->speckeyset)); jl_serialize_value(s, (jl_value_t*)m->name); @@ -731,6 +856,8 @@ static void jl_serialize_value_(jl_serializer_state *s, jl_value_t *v, int as_li internal = 1; else if (module_in_worklist(mi->def.method->module)) internal = 2; + else if (ptrhash_get(&external_mis, (void*)mi) != HT_NOTFOUND) + internal = 3; write_uint8(s->s, internal); if (!internal) { // also flag this in the backref table as special @@ -748,12 +875,12 @@ static void jl_serialize_value_(jl_serializer_state *s, jl_value_t *v, int as_li jl_array_t *backedges = mi->backedges; if (backedges) { // filter backedges to only contain pointers - // to items that we will actually store (internal == 2) + // to items that we will actually store (internal >= 2) size_t ins, i, l = jl_array_len(backedges); jl_method_instance_t **b_edges = (jl_method_instance_t**)jl_array_data(backedges); for (ins = i = 0; i < l; i++) { jl_method_instance_t *backedge = b_edges[i]; - if (module_in_worklist(backedge->def.method->module)) { + if (module_in_worklist(backedge->def.method->module) || method_instance_in_queue(backedge)) { b_edges[ins++] = backedge; } } @@ -764,10 +891,10 @@ static void jl_serialize_value_(jl_serializer_state *s, jl_value_t *v, int as_li } jl_serialize_value(s, (jl_value_t*)backedges); jl_serialize_value(s, (jl_value_t*)NULL); //callbacks - jl_serialize_code_instance(s, mi->cache, 1); + jl_serialize_code_instance(s, mi->cache, 1, internal); } else if (jl_is_code_instance(v)) { - jl_serialize_code_instance(s, (jl_code_instance_t*)v, 0); + jl_serialize_code_instance(s, (jl_code_instance_t*)v, 0, 2); } else if (jl_typeis(v, jl_module_type)) { jl_serialize_module(s, (jl_module_t*)v); @@ -936,6 +1063,27 @@ static void jl_serialize_value_(jl_serializer_state *s, jl_value_t *v, int as_li } } +// Used to serialize the external method instances queued in queued_method_roots (from newly_inferred) +static void serialize_htable_keys(jl_serializer_state *s, htable_t *ht, int nitems) +{ + write_int32(s->s, nitems); + void **table = ht->table; + size_t i, n = 0, sz = ht->size; + for (i = 0; i < sz; i += 2) { + if (table[i+1] != HT_NOTFOUND) { + jl_serialize_value(s, (jl_value_t*)table[i]); + n += 1; + } + } + assert(n == nitems); +} + +// Create the forward-edge map (caller => callees) +// the intent of these functions is to invert the backedges tree +// for anything that points to a method not part of the worklist +// or method instances not in the queue +// +// from MethodTables static void jl_collect_missing_backedges_to_mod(jl_methtable_t *mt) { jl_array_t *backedges = mt->backedges; @@ -943,7 +1091,7 @@ static void jl_collect_missing_backedges_to_mod(jl_methtable_t *mt) size_t i, l = jl_array_len(backedges); for (i = 1; i < l; i += 2) { jl_method_instance_t *caller = (jl_method_instance_t*)jl_array_ptr_ref(backedges, i); - jl_value_t *missing_callee = jl_array_ptr_ref(backedges, i - 1); + jl_value_t *missing_callee = jl_array_ptr_ref(backedges, i - 1); // signature of abstract callee jl_array_t **edges = (jl_array_t**)ptrhash_bp(&edges_map, (void*)caller); if (*edges == HT_NOTFOUND) *edges = jl_alloc_vec_any(0); @@ -952,8 +1100,7 @@ static void jl_collect_missing_backedges_to_mod(jl_methtable_t *mt) } } -// the intent of this function is to invert the backedges tree -// for anything that points to a method not part of the worklist +// from MethodInstances static void collect_backedges(jl_method_instance_t *callee) JL_GC_DISABLED { jl_array_t *backedges = callee->backedges; @@ -970,6 +1117,11 @@ static void collect_backedges(jl_method_instance_t *callee) JL_GC_DISABLED } +// For functions owned by modules not on the worklist, call this on each method. +// - if the method is owned by a worklist module, add it to the list of things to be +// fully serialized +// - otherwise (i.e., if it's an external method), check all of its specializations. +// Collect backedges from those that are not being fully serialized. static int jl_collect_methcache_from_mod(jl_typemap_entry_t *ml, void *closure) JL_GC_DISABLED { jl_array_t *s = (jl_array_t*)closure; @@ -983,7 +1135,7 @@ static int jl_collect_methcache_from_mod(jl_typemap_entry_t *ml, void *closure) size_t i, l = jl_svec_len(specializations); for (i = 0; i < l; i++) { jl_method_instance_t *callee = (jl_method_instance_t*)jl_svecref(specializations, i); - if ((jl_value_t*)callee != jl_nothing) + if ((jl_value_t*)callee != jl_nothing && !method_instance_in_queue(callee)) collect_backedges(callee); } } @@ -1074,7 +1226,7 @@ static void jl_collect_backedges( /* edges */ jl_array_t *s, /* ext_targets */ j for (i = 0; i < edges_map.size; i += 2) { jl_method_instance_t *caller = (jl_method_instance_t*)table[i]; jl_array_t *callees = (jl_array_t*)table[i + 1]; - if (callees != HT_NOTFOUND && module_in_worklist(caller->def.method->module)) { + if (callees != HT_NOTFOUND && (module_in_worklist(caller->def.method->module) || method_instance_in_queue(caller))) { size_t i, l = jl_array_len(callees); for (i = 0; i < l; i++) { jl_value_t *c = jl_array_ptr_ref(callees, i); @@ -1556,6 +1708,24 @@ static jl_value_t *jl_deserialize_value_method(jl_serializer_state *s, jl_value_ assert(loc != NULL && loc != HT_NOTFOUND); arraylist_push(&flagref_list, loc); arraylist_push(&flagref_list, (void*)pos); + if (serialization_mode & METHOD_HAS_NEW_ROOTS) { + uint64_t key = read_uint64(s->s); + int i, nnew = read_int32(s->s); + jl_array_t *newroots = jl_alloc_vec_any(nnew); + jl_value_t **data = (jl_value_t**)jl_array_data(newroots); + for (i = 0; i < nnew; i++) + data[i] = jl_deserialize_value(s, &(data[i])); + // Storing the new roots in `m->roots` risks losing them due to recaching + // (which replaces pointers to `m` with ones to the "live" method). + // Put them in separate storage so we can find them later. + assert(ptrhash_get(&queued_method_roots, m) == HT_NOTFOUND); + // In storing the key, on 32-bit platforms we need two slots. Might as well do this for all platforms. + jl_svec_t *qmrval = jl_alloc_svec_uninit(3); // GC is disabled + jl_svec_data(qmrval)[0] = (jl_value_t*)(uintptr_t)(key & ((((uint64_t)1) << 32) - 1)); // lo bits + jl_svec_data(qmrval)[1] = (jl_value_t*)(uintptr_t)((key >> 32) & ((((uint64_t)1) << 32) - 1)); // hi bits + jl_svec_data(qmrval)[2] = (jl_value_t*)newroots; + ptrhash_put(&queued_method_roots, m, qmrval); + } return (jl_value_t*)m; } m->specializations = (jl_svec_t*)jl_deserialize_value(s, (jl_value_t**)&m->specializations); @@ -1619,6 +1789,10 @@ static jl_value_t *jl_deserialize_value_method_instance(jl_serializer_state *s, uintptr_t pos = backref_list.len; arraylist_push(&backref_list, mi); int internal = read_uint8(s->s); + if (internal == 1) { + mi->uninferred = jl_deserialize_value(s, &mi->uninferred); + jl_gc_wb(mi, mi->uninferred); + } mi->specTypes = (jl_value_t*)jl_deserialize_value(s, (jl_value_t**)&mi->specTypes); jl_gc_wb(mi, mi->specTypes); mi->def.value = jl_deserialize_value(s, &mi->def.value); @@ -1631,10 +1805,6 @@ static jl_value_t *jl_deserialize_value_method_instance(jl_serializer_state *s, return (jl_value_t*)mi; } - if (internal == 1) { - mi->uninferred = jl_deserialize_value(s, &mi->uninferred); - jl_gc_wb(mi, mi->uninferred); - } mi->sparam_vals = (jl_svec_t*)jl_deserialize_value(s, (jl_value_t**)&mi->sparam_vals); jl_gc_wb(mi, mi->sparam_vals); mi->backedges = (jl_array_t*)jl_deserialize_value(s, (jl_value_t**)&mi->backedges); @@ -1676,6 +1846,7 @@ static jl_value_t *jl_deserialize_value_code_instance(jl_serializer_state *s, jl if ((flags >> 3) & 1) codeinst->precompile = 1; codeinst->relocatability = read_uint8(s->s); + assert(codeinst->relocatability <= 1); codeinst->next = (jl_code_instance_t*)jl_deserialize_value(s, (jl_value_t**)&codeinst->next); jl_gc_wb(codeinst, codeinst->next); if (validate) { @@ -2023,15 +2194,121 @@ static void jl_insert_methods(jl_array_t *list) size_t i, l = jl_array_len(list); for (i = 0; i < l; i += 2) { jl_method_t *meth = (jl_method_t*)jl_array_ptr_ref(list, i); + assert(jl_is_method(meth)); assert(!meth->is_for_opaque_closure); jl_tupletype_t *simpletype = (jl_tupletype_t*)jl_array_ptr_ref(list, i + 1); - assert(jl_is_method(meth)); jl_methtable_t *mt = jl_method_get_table(meth); assert((jl_value_t*)mt != jl_nothing); jl_method_table_insert(mt, meth, simpletype); } } +void remove_code_instance_from_validation(jl_code_instance_t *codeinst) +{ + ptrhash_remove(&new_code_instance_validate, codeinst); +} + +static void jl_insert_method_instances(jl_array_t *list) +{ + size_t i, l = jl_array_len(list); + // Validate the MethodInstances + jl_array_t *valids = jl_alloc_array_1d(jl_array_uint8_type, l); + memset(jl_array_data(valids), 1, l); + size_t world = jl_atomic_load_acquire(&jl_world_counter); + for (i = 0; i < l; i++) { + jl_method_instance_t *mi = (jl_method_instance_t*)jl_array_ptr_ref(list, i); + assert(jl_is_method_instance(mi)); + if (jl_is_method(mi->def.method)) { + // Is this still the method we'd be calling? + jl_methtable_t *mt = jl_method_table_for(mi->specTypes); + struct jl_typemap_assoc search = {(jl_value_t*)mi->specTypes, world, NULL, 0, ~(size_t)0}; + jl_typemap_entry_t *entry = jl_typemap_assoc_by_type(mt->defs, &search, /*offs*/0, /*subtype*/1); + if (entry) { + jl_value_t *mworld = entry->func.value; + if (jl_is_method(mworld) && mi->def.method != (jl_method_t*)mworld && jl_type_morespecific(((jl_method_t*)mworld)->sig, mi->def.method->sig)) { + jl_array_uint8_set(valids, i, 0); + invalidate_backedges(&remove_code_instance_from_validation, mi, world, "jl_insert_method_instance"); + // The codeinst of this mi haven't yet been removed + jl_code_instance_t *codeinst = mi->cache; + while (codeinst) { + remove_code_instance_from_validation(codeinst); + codeinst = codeinst->next; + } + if (_jl_debug_method_invalidation) { + jl_array_ptr_1d_push(_jl_debug_method_invalidation, mworld); + jl_array_ptr_1d_push(_jl_debug_method_invalidation, jl_cstr_to_string("jl_method_table_insert")); // GC disabled + } + } + } + } + } + // While it's tempting to just remove the invalidated MIs altogether, + // this hurts the ability of SnoopCompile to diagnose problems. + for (i = 0; i < l; i++) { + jl_method_instance_t *mi = (jl_method_instance_t*)jl_array_ptr_ref(list, i); + jl_method_instance_t *milive = jl_specializations_get_or_insert(mi); + ptrhash_put(&uniquing_table, mi, milive); // store the association for the 2nd pass + } + // We may need to fix up the backedges for the ones that didn't "go live" + for (i = 0; i < l; i++) { + jl_method_instance_t *mi = (jl_method_instance_t*)jl_array_ptr_ref(list, i); + jl_method_instance_t *milive = (jl_method_instance_t*)ptrhash_get(&uniquing_table, mi); + if (milive != mi) { + // A previously-loaded module compiled this method, so the one we deserialized will be dropped. + // But make sure the backedges are copied over. + if (mi->backedges) { + if (!milive->backedges) { + // Copy all the backedges (after looking up the live ones) + size_t j, n = jl_array_len(mi->backedges); + milive->backedges = jl_alloc_vec_any(n); + jl_gc_wb(milive, milive->backedges); + for (j = 0; j < n; j++) { + jl_method_instance_t *be = (jl_method_instance_t*)jl_array_ptr_ref(mi->backedges, j); + jl_method_instance_t *belive = (jl_method_instance_t*)ptrhash_get(&uniquing_table, be); + if (belive == HT_NOTFOUND) + belive = be; + jl_array_ptr_set(milive->backedges, j, belive); + } + } else { + // Copy the missing backedges (this is an O(N^2) algorithm, but many methods have few MethodInstances) + size_t j, k, n = jl_array_len(mi->backedges), nlive = jl_array_len(milive->backedges); + for (j = 0; j < n; j++) { + jl_method_instance_t *be = (jl_method_instance_t*)jl_array_ptr_ref(mi->backedges, j); + jl_method_instance_t *belive = (jl_method_instance_t*)ptrhash_get(&uniquing_table, be); + if (belive == HT_NOTFOUND) + belive = be; + int found = 0; + for (k = 0; k < nlive; k++) { + if (belive == (jl_method_instance_t*)jl_array_ptr_ref(milive->backedges, k)) { + found = 1; + break; + } + } + if (!found) + jl_array_ptr_1d_push(milive->backedges, (jl_value_t*)belive); + } + } + } + // Additionally, if we have CodeInstance(s) and the running CodeInstance is world-limited, transfer it + if (mi->cache && jl_array_uint8_ref(valids, i)) { + if (!milive->cache || milive->cache->max_world < ~(size_t)0) { + jl_code_instance_t *cilive = milive->cache, *ci; + milive->cache = mi->cache; + jl_gc_wb(milive, milive->cache); + ci = mi->cache; + ci->def = milive; + while (ci->next) { + ci = ci->next; + ci->def = milive; + } + ci->next = cilive; + jl_gc_wb(ci, ci->next); + } + } + } + } +} + // verify that these edges intersect with the same methods as before static void jl_verify_edges(jl_array_t *targets, jl_array_t **pvalids) { @@ -2092,7 +2369,7 @@ static void jl_verify_edges(jl_array_t *targets, jl_array_t **pvalids) // Restore backedges to external targets // `targets` is [callee1, matches1, ...], the global set of non-worklist callees of worklist-owned methods. -// `edges` = [caller1, targets_indexes1, ...], the list of worklist-owned methods calling external methods. +// `list` = [caller1, targets_indexes1, ...], the list of worklist-owned methods calling external methods. static void jl_insert_backedges(jl_array_t *list, jl_array_t *targets) { // map(enable, ((list[i] => targets[list[i + 1] .* 2]) for i in 1:2:length(list) if all(valids[list[i + 1]]))) @@ -2104,7 +2381,6 @@ static void jl_insert_backedges(jl_array_t *list, jl_array_t *targets) for (i = 0; i < l; i += 2) { jl_method_instance_t *caller = (jl_method_instance_t*)jl_array_ptr_ref(list, i); assert(jl_is_method_instance(caller) && jl_is_method(caller->def.method)); - assert(caller->def.method->primary_world == jl_atomic_load_acquire(&jl_world_counter)); // caller should be new jl_array_t *idxs_array = (jl_array_t*)jl_array_ptr_ref(list, i + 1); assert(jl_isa((jl_value_t*)idxs_array, jl_array_int32_type)); int32_t *idxs = (int32_t*)jl_array_data(idxs_array); @@ -2124,14 +2400,18 @@ static void jl_insert_backedges(jl_array_t *list, jl_array_t *targets) } else { jl_methtable_t *mt = jl_method_table_for(callee); - assert((jl_value_t*)mt != jl_nothing); - jl_method_table_add_backedge(mt, callee, (jl_value_t*)caller); + // FIXME: rarely, `callee` has an unexpected `Union` signature, + // see https://github.com/JuliaLang/julia/pull/43990#issuecomment-1030329344 + // Fix the issue and turn this back into an `assert((jl_value_t*)mt != jl_nothing)` + // This workaround exposes us to (rare) 265-violations. + if ((jl_value_t*)mt != jl_nothing) + jl_method_table_add_backedge(mt, callee, (jl_value_t*)caller); } } // then enable it jl_code_instance_t *codeinst = caller->cache; while (codeinst) { - if (codeinst->min_world > 0) + if (ptrhash_get(&new_code_instance_validate, codeinst) != HT_NOTFOUND && codeinst->min_world > 0) codeinst->max_world = ~(size_t)0; ptrhash_remove(&new_code_instance_validate, codeinst); // mark it as handled codeinst = jl_atomic_load_relaxed(&codeinst->next); @@ -2321,6 +2601,14 @@ JL_DLLEXPORT void jl_init_restored_modules(jl_array_t *init_order) // --- entry points --- +// Register all newly-inferred MethodInstances +// This gets called as the final step of Base.include_package_for_output +JL_DLLEXPORT void jl_set_newly_inferred(jl_value_t* _newly_inferred) +{ + assert(_newly_inferred == NULL || jl_is_array(_newly_inferred)); + newly_inferred = (jl_array_t*) _newly_inferred; +} + // Serialize the modules in `worklist` to file `fname` JL_DLLEXPORT int jl_save_incremental(const char *fname, jl_array_t *worklist) { @@ -2352,6 +2640,7 @@ JL_DLLEXPORT int jl_save_incremental(const char *fname, jl_array_t *worklist) arraylist_new(&reinit_list, 0); htable_new(&edges_map, 0); htable_new(&backref_table, 5000); + htable_new(&external_mis, 0); ptrhash_put(&backref_table, jl_main_module, (char*)HT_NOTFOUND + 1); backref_table_numel = 1; jl_idtable_type = jl_base_module ? jl_get_global(jl_base_module, jl_symbol("IdDict")) : NULL; @@ -2367,6 +2656,8 @@ JL_DLLEXPORT int jl_save_incremental(const char *fname, jl_array_t *worklist) jl_array_t *ext_targets = jl_alloc_vec_any(0); // [callee1, matches1, ...] non-worklist callees of worklist-owned methods jl_array_t *edges = jl_alloc_vec_any(0); // [caller1, ext_targets_indexes1, ...] for worklist-owned methods calling external methods + int n_ext_mis = queue_external_mis(newly_inferred); + size_t i; size_t len = jl_array_len(mod_array); for (i = 0; i < len; i++) { @@ -2390,8 +2681,11 @@ JL_DLLEXPORT int jl_save_incremental(const char *fname, jl_array_t *worklist) mod_array }; jl_serialize_value(&s, worklist); // serialize module-owned items (those accessible from the bindings table) - jl_serialize_value(&s, extext_methods); // serialize new methods for external functions - // The next two allow us to restore backedges from external MethodInstances to internal ones + jl_serialize_value(&s, extext_methods); // serialize new worklist-owned methods for external functions + serialize_htable_keys(&s, &external_mis, n_ext_mis); // serialize external MethodInstances + + // The next two allow us to restore backedges from external "unserialized" (stub-serialized) MethodInstances + // to the ones we serialize here jl_serialize_value(&s, edges); jl_serialize_value(&s, ext_targets); jl_finalize_serializer(&s); @@ -2400,6 +2694,7 @@ JL_DLLEXPORT int jl_save_incremental(const char *fname, jl_array_t *worklist) jl_gc_enable(en); htable_reset(&edges_map, 0); htable_reset(&backref_table, 0); + htable_reset(&external_mis, 0); arraylist_free(&reinit_list); // Write the source-text for the dependent files @@ -2630,12 +2925,12 @@ static jl_method_t *jl_lookup_method(jl_methtable_t *mt, jl_datatype_t *sig, siz static jl_method_t *jl_recache_method(jl_method_t *m) { assert(!m->is_for_opaque_closure); + assert(jl_is_method(m)); jl_datatype_t *sig = (jl_datatype_t*)m->sig; jl_methtable_t *mt = jl_method_get_table(m); assert((jl_value_t*)mt != jl_nothing); jl_set_typeof(m, (void*)(intptr_t)0x30); // invalidate the old value to help catch errors - jl_method_t *_new = jl_lookup_method(mt, sig, m->module->primary_world); - return _new; + return jl_lookup_method(mt, sig, m->module->primary_world); } static jl_value_t *jl_recache_other_(jl_value_t *o); @@ -2694,6 +2989,34 @@ static void jl_recache_other(void) flagref_list.len = 0; } +// Wait to copy roots until recaching is done +// This is because recaching requires that all pointers to methods and methodinstances +// stay at their source location as recorded by flagref_list. Once recaching is complete, +// they can be safely copied over. +static void jl_copy_roots(void) +{ + size_t i, j, l; + for (i = 0; i < queued_method_roots.size; i+=2) { + jl_method_t *m = (jl_method_t*)queued_method_roots.table[i]; + m = (jl_method_t*)ptrhash_get(&uniquing_table, m); + jl_svec_t *keyroots = (jl_svec_t*)queued_method_roots.table[i+1]; + if (keyroots != HT_NOTFOUND) { + uint64_t key = (uint64_t)(uintptr_t)jl_svec_ref(keyroots, 0) | ((uint64_t)(uintptr_t)jl_svec_ref(keyroots, 1) << 32); + jl_array_t *roots = (jl_array_t*)jl_svec_ref(keyroots, 2); + assert(jl_is_array(roots)); + l = jl_array_len(roots); + for (j = 0; j < l; j++) { + jl_value_t *r = jl_array_ptr_ref(roots, j); + jl_value_t *newr = (jl_value_t*)ptrhash_get(&uniquing_table, r); + if (newr != HT_NOTFOUND) { + jl_array_ptr_set(roots, j, newr); + } + } + jl_append_method_roots(m, key, roots); + } + } +} + static int trace_method(jl_typemap_entry_t *entry, void *closure) { jl_call_tracer(jl_newmeth_tracer, (jl_value_t*)entry->func.method); @@ -2741,6 +3064,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(&queued_method_roots, 0); htable_new(&new_code_instance_validate, 0); arraylist_new(&ccallable_list, 0); htable_new(&uniquing_table, 0); @@ -2756,6 +3080,11 @@ static jl_value_t *_jl_restore_incremental(ios_t *f, jl_array_t *mod_array) // See explanation in jl_save_incremental for variables of the same names jl_value_t *extext_methods = jl_deserialize_value(&s, &extext_methods); + int i, n_ext_mis = read_int32(s.s); + jl_array_t *mi_list = jl_alloc_vec_any(n_ext_mis); // reload MIs stored by serialize_htable_keys + jl_value_t **midata = (jl_value_t**)jl_array_data(mi_list); + for (i = 0; i < n_ext_mis; i++) + midata[i] = jl_deserialize_value(&s, &(midata[i])); jl_value_t *edges = jl_deserialize_value(&s, &edges); jl_value_t *ext_targets = jl_deserialize_value(&s, &ext_targets); @@ -2766,9 +3095,11 @@ static jl_value_t *_jl_restore_incremental(ios_t *f, jl_array_t *mod_array) // at this point, the AST is fully reconstructed, but still completely disconnected // now all of the interconnects will be created jl_recache_types(); // make all of the types identities correct - htable_reset(&uniquing_table, 0); jl_insert_methods((jl_array_t*)extext_methods); // hook up extension methods for external generic functions (needs to be after recache types) jl_recache_other(); // make all of the other objects identities correct (needs to be after insert methods) + jl_copy_roots(); // copying new roots of external methods (must wait until recaching is complete) + // At this point, the novel specializations in mi_list reference the real method, but they haven't been cached in its specializations + jl_insert_method_instances(mi_list); // insert novel specializations htable_free(&uniquing_table); jl_array_t *init_order = jl_finalize_deserializer(&s, tracee_list); // done with f and s (needs to be after recache) if (init_order == NULL) @@ -2787,6 +3118,7 @@ static jl_value_t *_jl_restore_incremental(ios_t *f, jl_array_t *mod_array) htable_free(&new_code_instance_validate); arraylist_free(&flagref_list); arraylist_free(&backref_list); + htable_free(&queued_method_roots); ios_close(f); jl_gc_enable_finalizers(ct, 1); // make sure we don't run any Julia code concurrently before this point diff --git a/src/gf.c b/src/gf.c index 25b29c63a0782..2b5d17c408299 100644 --- a/src/gf.c +++ b/src/gf.c @@ -99,7 +99,7 @@ static int speccache_eq(size_t idx, const void *ty, jl_svec_t *data, uint_t hv) } // get or create the MethodInstance for a specialization -JL_DLLEXPORT jl_method_instance_t *jl_specializations_get_linfo(jl_method_t *m JL_PROPAGATES_ROOT, jl_value_t *type, jl_svec_t *sparams) +static jl_method_instance_t *jl_specializations_get_linfo_(jl_method_t *m JL_PROPAGATES_ROOT, jl_value_t *type, jl_svec_t *sparams, jl_method_instance_t *mi_insert) { if (m->sig == (jl_value_t*)jl_anytuple_type && m->unspecialized) return m->unspecialized; // handle builtin methods @@ -150,7 +150,7 @@ JL_DLLEXPORT jl_method_instance_t *jl_specializations_get_linfo(jl_method_t *m J assert(!jl_types_equal(mi->specTypes, type)); } } - jl_method_instance_t *mi = jl_get_specialized(m, type, sparams); + jl_method_instance_t *mi = mi_insert ? mi_insert : jl_get_specialized(m, type, sparams); JL_GC_PUSH1(&mi); if (hv ? (i + 1 >= cl || jl_svecref(specializations, i + 1) != jl_nothing) : (i <= 1 || jl_svecref(specializations, i - 2) != jl_nothing)) { size_t ncl = cl < 8 ? 8 : (cl*3)>>1; @@ -184,6 +184,19 @@ JL_DLLEXPORT jl_method_instance_t *jl_specializations_get_linfo(jl_method_t *m J } } +JL_DLLEXPORT jl_method_instance_t *jl_specializations_get_linfo(jl_method_t *m JL_PROPAGATES_ROOT, jl_value_t *type, jl_svec_t *sparams) +{ + return jl_specializations_get_linfo_(m, type, sparams, NULL); +} + +jl_method_instance_t *jl_specializations_get_or_insert(jl_method_instance_t *mi) +{ + jl_method_t *m = mi->def.method; + jl_value_t *type = mi->specTypes; + jl_svec_t *sparams = mi->sparam_vals; + return jl_specializations_get_linfo_(m, type, sparams, mi); +} + JL_DLLEXPORT jl_value_t *jl_specializations_lookup(jl_method_t *m, jl_value_t *type) { jl_value_t *mi = (jl_value_t*)jl_specializations_get_linfo(m, type, NULL); @@ -1390,8 +1403,10 @@ static void invalidate_external(jl_method_instance_t *mi, size_t max_world) { } } +static void do_nothing_with_codeinst(jl_code_instance_t *ci) {} + // recursively invalidate cached methods that had an edge to a replaced method -static void invalidate_method_instance(jl_method_instance_t *replaced, size_t max_world, int depth) +static void invalidate_method_instance(void (*f)(jl_code_instance_t*), jl_method_instance_t *replaced, size_t max_world, int depth) { if (_jl_debug_method_invalidation) { jl_value_t *boxeddepth = NULL; @@ -1411,6 +1426,7 @@ static void invalidate_method_instance(jl_method_instance_t *replaced, size_t ma codeinst->max_world = max_world; } assert(codeinst->max_world <= max_world); + (*f)(codeinst); codeinst = jl_atomic_load_relaxed(&codeinst->next); } // recurse to all backedges to update their valid range also @@ -1420,14 +1436,14 @@ static void invalidate_method_instance(jl_method_instance_t *replaced, size_t ma size_t i, l = jl_array_len(backedges); for (i = 0; i < l; i++) { jl_method_instance_t *replaced = (jl_method_instance_t*)jl_array_ptr_ref(backedges, i); - invalidate_method_instance(replaced, max_world, depth + 1); + invalidate_method_instance(f, replaced, max_world, depth + 1); } } JL_UNLOCK(&replaced->def.method->writelock); } // invalidate cached methods that overlap this definition -static void invalidate_backedges(jl_method_instance_t *replaced_mi, size_t max_world, const char *why) +void invalidate_backedges(void (*f)(jl_code_instance_t*), jl_method_instance_t *replaced_mi, size_t max_world, const char *why) { JL_LOCK(&replaced_mi->def.method->writelock); jl_array_t *backedges = replaced_mi->backedges; @@ -1437,7 +1453,7 @@ static void invalidate_backedges(jl_method_instance_t *replaced_mi, size_t max_w size_t i, l = jl_array_len(backedges); jl_method_instance_t **replaced = (jl_method_instance_t**)jl_array_ptr_data(backedges); for (i = 0; i < l; i++) { - invalidate_method_instance(replaced[i], max_world, 1); + invalidate_method_instance(f, replaced[i], max_world, 1); } } JL_UNLOCK(&replaced_mi->def.method->writelock); @@ -1600,7 +1616,7 @@ static void jl_method_table_invalidate(jl_methtable_t *mt, jl_typemap_entry_t *m if ((jl_value_t*)mi != jl_nothing) { invalidated = 1; invalidate_external(mi, methodentry->max_world); - invalidate_backedges(mi, methodentry->max_world, "jl_method_table_disable"); + invalidate_backedges(&do_nothing_with_codeinst, mi, methodentry->max_world, "jl_method_table_disable"); } } if (invalidated && _jl_debug_method_invalidation) { @@ -1731,7 +1747,7 @@ JL_DLLEXPORT void jl_method_table_insert(jl_methtable_t *mt, jl_method_t *method if (missing) { jl_method_instance_t *backedge = (jl_method_instance_t*)backedges[i]; invalidate_external(backedge, max_world); - invalidate_method_instance(backedge, max_world, 0); + invalidate_method_instance(&do_nothing_with_codeinst, backedge, max_world, 0); invalidated = 1; if (_jl_debug_method_invalidation) jl_array_ptr_1d_push(_jl_debug_method_invalidation, (jl_value_t*)backedgetyp); @@ -1801,7 +1817,7 @@ JL_DLLEXPORT void jl_method_table_insert(jl_methtable_t *mt, jl_method_t *method invalidate_external(mi, max_world); if (mi->backedges) { invalidated = 1; - invalidate_backedges(mi, max_world, "jl_method_table_insert"); + invalidate_backedges(&do_nothing_with_codeinst, mi, max_world, "jl_method_table_insert"); } } } @@ -2238,6 +2254,7 @@ JL_DLLEXPORT int jl_compile_hint(jl_tupletype_t *types) if (mi == NULL) return 0; JL_GC_PROMISE_ROOTED(mi); + mi->precompiled = 1; if (jl_generating_output()) { jl_compile_now(mi); // In addition to full compilation of the compilation-signature, if `types` is more specific (e.g. due to nospecialize), @@ -2252,6 +2269,7 @@ JL_DLLEXPORT int jl_compile_hint(jl_tupletype_t *types) types2 = jl_type_intersection_env((jl_value_t*)types, (jl_value_t*)mi->def.method->sig, &tpenv2); jl_method_instance_t *li2 = jl_specializations_get_linfo(mi->def.method, (jl_value_t*)types2, tpenv2); JL_GC_POP(); + li2->precompiled = 1; if (jl_rettype_inferred(li2, world, world) == jl_nothing) (void)jl_type_infer(li2, world, 1); if (jl_typeinf_func && mi->def.method->primary_world <= tworld) { diff --git a/src/jltypes.c b/src/jltypes.c index cb9141dd50fd4..a24e9f7e488bd 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -2466,7 +2466,7 @@ void jl_init_types(void) JL_GC_DISABLED jl_method_instance_type = jl_new_datatype(jl_symbol("MethodInstance"), core, jl_any_type, jl_emptysvec, - jl_perm_symsvec(8, + jl_perm_symsvec(9, "def", "specTypes", "sparam_vals", @@ -2474,8 +2474,9 @@ void jl_init_types(void) JL_GC_DISABLED "backedges", "callbacks", "cache", - "inInference"), - jl_svec(8, + "inInference", + "precompiled"), + jl_svec(9, jl_new_struct(jl_uniontype_type, jl_method_type, jl_module_type), jl_any_type, jl_simplevector_type, @@ -2483,6 +2484,7 @@ void jl_init_types(void) JL_GC_DISABLED jl_any_type, jl_any_type, jl_any_type, + jl_bool_type, jl_bool_type), jl_emptysvec, 0, 1, 3); diff --git a/src/julia.h b/src/julia.h index d726162b88213..afb0d00630dbd 100644 --- a/src/julia.h +++ b/src/julia.h @@ -361,6 +361,7 @@ struct _jl_method_instance_t { jl_array_t *callbacks; // list of callback functions to inform external caches about invalidations _Atomic(struct _jl_code_instance_t*) cache; uint8_t inInference; // flags to tell if inference is running on this object + uint8_t precompiled; // true if this instance was generated by an explicit `precompile(...)` call }; // OpaqueClosure @@ -1723,6 +1724,7 @@ JL_DLLEXPORT ios_t *jl_create_system_image(void *); JL_DLLEXPORT void jl_save_system_image(const char *fname); JL_DLLEXPORT void jl_restore_system_image(const char *fname); JL_DLLEXPORT void jl_restore_system_image_data(const char *buf, size_t len); +JL_DLLEXPORT void jl_set_newly_inferred(jl_value_t *newly_inferred); JL_DLLEXPORT int jl_save_incremental(const char *fname, jl_array_t *worklist); JL_DLLEXPORT jl_value_t *jl_restore_incremental(const char *fname, jl_array_t *depmods); JL_DLLEXPORT jl_value_t *jl_restore_incremental_from_buf(const char *buf, size_t sz, jl_array_t *depmods); diff --git a/src/julia_internal.h b/src/julia_internal.h index 3d43584faf0c4..21c46129b7149 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -223,6 +223,7 @@ extern tracer_cb jl_newmeth_tracer; void jl_call_tracer(tracer_cb callback, jl_value_t *tracee); void print_func_loc(JL_STREAM *s, jl_method_t *m); extern jl_array_t *_jl_debug_method_invalidation JL_GLOBALLY_ROOTED; +void invalidate_backedges(void (*f)(jl_code_instance_t*), jl_method_instance_t *replaced_mi, size_t max_world, const char *why); extern JL_DLLEXPORT size_t jl_page_size; extern jl_function_t *jl_typeinf_func; @@ -535,8 +536,10 @@ void jl_resolve_globals_in_ir(jl_array_t *stmts, jl_module_t *m, jl_svec_t *spar int binding_effects); JL_DLLEXPORT void jl_add_method_root(jl_method_t *m, jl_module_t *mod, jl_value_t* root); +void jl_append_method_roots(jl_method_t *m, uint64_t modid, jl_array_t* roots); int get_root_reference(rle_reference *rr, jl_method_t *m, size_t i); jl_value_t *lookup_root(jl_method_t *m, uint64_t key, int index); +int nroots_with_key(jl_method_t *m, uint64_t key); int jl_valid_type_param(jl_value_t *v); @@ -864,6 +867,7 @@ JL_DLLEXPORT jl_code_instance_t *jl_method_compiled(jl_method_instance_t *mi JL_ JL_DLLEXPORT jl_value_t *jl_methtable_lookup(jl_methtable_t *mt, jl_value_t *type, size_t world); JL_DLLEXPORT jl_method_instance_t *jl_specializations_get_linfo( jl_method_t *m JL_PROPAGATES_ROOT, jl_value_t *type, jl_svec_t *sparams); +jl_method_instance_t *jl_specializations_get_or_insert(jl_method_instance_t *mi_ins); JL_DLLEXPORT void jl_method_instance_add_backedge(jl_method_instance_t *callee, jl_method_instance_t *caller); JL_DLLEXPORT void jl_method_table_add_backedge(jl_methtable_t *mt, jl_value_t *typ, jl_value_t *caller); diff --git a/src/method.c b/src/method.c index f71bb8803caf0..7325670bd76a4 100644 --- a/src/method.c +++ b/src/method.c @@ -439,6 +439,7 @@ JL_DLLEXPORT jl_method_instance_t *jl_new_method_instance_uninit(void) li->callbacks = NULL; jl_atomic_store_relaxed(&li->cache, NULL); li->inInference = 0; + li->precompiled = 0; return li; } @@ -1033,15 +1034,8 @@ static void add_root_block(jl_array_t *root_blocks, uint64_t modid, size_t len) blocks[nx2-1] = len; } -JL_DLLEXPORT void jl_add_method_root(jl_method_t *m, jl_module_t *mod, jl_value_t* root) +static void prepare_method_for_roots(jl_method_t *m, uint64_t modid) { - JL_GC_PUSH2(&m, &root); - uint64_t modid = 0; - if (mod) { - assert(jl_is_module(mod)); - modid = mod->build_id; - } - assert(jl_is_method(m)); if (!m->roots) { m->roots = jl_alloc_vec_any(0); jl_gc_wb(m, m->roots); @@ -1050,12 +1044,35 @@ JL_DLLEXPORT void jl_add_method_root(jl_method_t *m, jl_module_t *mod, jl_value_ m->root_blocks = jl_alloc_array_1d(jl_array_uint64_type, 0); jl_gc_wb(m, m->root_blocks); } +} + +JL_DLLEXPORT void jl_add_method_root(jl_method_t *m, jl_module_t *mod, jl_value_t* root) +{ + JL_GC_PUSH2(&m, &root); + uint64_t modid = 0; + if (mod) { + assert(jl_is_module(mod)); + modid = mod->build_id; + } + assert(jl_is_method(m)); + prepare_method_for_roots(m, modid); if (current_root_id(m->root_blocks) != modid) add_root_block(m->root_blocks, modid, jl_array_len(m->roots)); jl_array_ptr_1d_push(m->roots, root); JL_GC_POP(); } +void jl_append_method_roots(jl_method_t *m, uint64_t modid, jl_array_t* roots) +{ + JL_GC_PUSH2(&m, &roots); + assert(jl_is_method(m)); + assert(jl_is_array(roots)); + prepare_method_for_roots(m, modid); + add_root_block(m->root_blocks, modid, jl_array_len(m->roots)); + jl_array_ptr_1d_append(m->roots, roots); + JL_GC_POP(); +} + // given the absolute index i of a root, retrieve its relocatable reference // returns 1 if the root is relocatable int get_root_reference(rle_reference *rr, jl_method_t *m, size_t i) @@ -1084,6 +1101,23 @@ jl_value_t *lookup_root(jl_method_t *m, uint64_t key, int index) return jl_array_ptr_ref(m->roots, i); } +int nroots_with_key(jl_method_t *m, uint64_t key) +{ + size_t nroots = 0; + if (m->roots) + nroots = jl_array_len(m->roots); + if (!m->root_blocks) + return key == 0 ? nroots : 0; + uint64_t *rletable = (uint64_t*)jl_array_data(m->root_blocks); + size_t j, nblocks2 = jl_array_len(m->root_blocks); + int nwithkey = 0; + for (j = 0; j < nblocks2; j+=2) { + if (rletable[j] == key) + nwithkey += (j+3 < nblocks2 ? rletable[j+3] : nroots) - rletable[j+1]; + } + return nwithkey; +} + #ifdef __cplusplus } #endif diff --git a/stdlib/Artifacts/src/Artifacts.jl b/stdlib/Artifacts/src/Artifacts.jl index 645e77944208b..6d3bdb5fb674b 100644 --- a/stdlib/Artifacts/src/Artifacts.jl +++ b/stdlib/Artifacts/src/Artifacts.jl @@ -272,17 +272,17 @@ function unpack_platform(entry::Dict{String,Any}, name::String, end # Collect all String-valued mappings in `entry` and use them as tags - tags = Dict{Symbol, String}() + tags = Dict{String, String}() for (k, v) in entry if v isa String - tags[Symbol(k)] = v + tags[k] = v end end # Removing some known entries that shouldn't be passed through `tags` - delete!(tags, :os) - delete!(tags, :arch) - delete!(tags, Symbol("git-tree-sha1")) - return Platform(entry["arch"], entry["os"]; tags...) + delete!(tags, "os") + delete!(tags, "arch") + delete!(tags, "git-tree-sha1") + return Platform(entry["arch"], entry["os"], tags) end function pack_platform!(meta::Dict, p::AbstractPlatform) @@ -718,4 +718,9 @@ split_artifact_slash(name::AbstractString) = artifact_slash_lookup(name::AbstractString, artifact_dict::Dict, artifacts_toml::AbstractString) = artifact_slash_lookup(String(name)::String, artifact_dict, String(artifacts_toml)::String) +# Precompilation to reduce latency +precompile(load_artifacts_toml, (String,)) +precompile(NamedTuple{(:pkg_uuid,)}, (Tuple{Base.UUID},)) +precompile(Core.kwfunc(load_artifacts_toml), (NamedTuple{(:pkg_uuid,), Tuple{Base.UUID}}, typeof(load_artifacts_toml), String)) + end # module Artifacts diff --git a/test/precompile.jl b/test/precompile.jl index 411267705622d..d39dcd9f7ccb8 100644 --- a/test/precompile.jl +++ b/test/precompile.jl @@ -83,7 +83,6 @@ function group_roots(iter::RLEIterator) return rootsby end - precompile_test_harness("basic precompile functionality") do dir2 precompile_test_harness(false) do dir Foo_file = joinpath(dir, "$Foo_module.jl") @@ -585,11 +584,11 @@ precompile_test_harness(false) do dir end end -# method root provenance -# setindex!(::Dict{K,V}, ::Any, ::K) adds both compression and codegen roots +# method root provenance & external code caching precompile_test_harness("code caching") do dir Bid = rootid(Base) Cache_module = :Cacheb8321416e8a3e2f1 + # Note: calling setindex!(::Dict{K,V}, ::Any, ::K) adds both compression and codegen roots write(joinpath(dir, "$Cache_module.jl"), """ module $Cache_module @@ -619,33 +618,59 @@ precompile_test_harness("code caching") do dir Base.compilecache(Base.PkgId(string(Cache_module))) @eval using $Cache_module M = getfield(@__MODULE__, Cache_module) + # Test that this cache file "owns" all the roots Mid = rootid(M) for name in (:f, :fpush, :callboth) func = getfield(M, name) m = only(collect(methods(func))) @test all(i -> root_provenance(m, i) == Mid, 1:length(m.roots)) end + # Check that we can cache external CodeInstances: + # size(::Vector) has an inferred specialization for Vector{X} + msize = which(size, (Vector{<:Any},)) + hasspec = false + for i = 1:length(msize.specializations) + if isassigned(msize.specializations, i) + mi = msize.specializations[i] + if isa(mi, Core.MethodInstance) + tt = Base.unwrap_unionall(mi.specTypes) + if tt.parameters[2] == Vector{Cacheb8321416e8a3e2f1.X} + if isdefined(mi, :cache) && isa(mi.cache, Core.CodeInstance) && mi.cache.max_world == typemax(UInt) && mi.cache.inferred !== nothing + hasspec = true + break + end + end + end + end + end + @test hasspec + # Test that compilation adds to method roots with appropriate provenance m = which(setindex!, (Dict{M.X,Any}, Any, M.X)) - @test_broken M.X ∈ m.roots # requires caching external compilation results + @test M.X ∈ m.roots + # Check that roots added outside of incremental builds get attributed to a moduleid of 0 Base.invokelatest() do Dict{M.X2,Any}()[M.X2()] = nothing end @test M.X2 ∈ m.roots groups = group_roots(m) - @test_broken M.X ∈ groups[Mid] # requires caching external compilation results - @test M.X2 ∈ groups[rootid(@__MODULE__)] + @test M.X ∈ groups[Mid] # attributed to M + @test M.X2 ∈ groups[0] # activate module is not known @test !isempty(groups[Bid]) + # Check that internal methods and their roots are accounted appropriately minternal = which(M.getelsize, (Vector,)) mi = minternal.specializations[1] + @test Base.unwrap_unionall(mi.specTypes).parameters[2] == Vector{Int32} ci = mi.cache @test ci.relocatability == 1 + @test ci.inferred !== nothing + # ...and that we can add "untracked" roots & non-relocatable CodeInstances to them too Base.invokelatest() do M.getelsize(M.X2[]) end mi = minternal.specializations[2] ci = mi.cache @test ci.relocatability == 0 - # PkgA loads PkgB, and both add roots to the same method (both before and after loading B) + # PkgA loads PkgB, and both add roots to the same `push!` method (both before and after loading B) Cache_module2 = :Cachea1544c83560f0c99 write(joinpath(dir, "$Cache_module2.jl"), """ @@ -677,11 +702,175 @@ precompile_test_harness("code caching") do dir end mT = which(push!, (Vector{T} where T, Any)) groups = group_roots(mT) - # all below require caching external CodeInstances - @test_broken M2.Y ∈ groups[M2id] - @test_broken M2.Z ∈ groups[M2id] - @test_broken M.X ∈ groups[Mid] - @test_broken M.X ∉ groups[M2id] + @test M2.Y ∈ groups[M2id] + @test M2.Z ∈ groups[M2id] + @test M.X ∈ groups[Mid] + @test M.X ∉ groups[M2id] + # backedges of external MethodInstances + # Root gets used by RootA and RootB, and both consumers end up inferring the same MethodInstance from Root + # Do both callers get listed as backedges? + RootModule = :Root_0xab07d60518763a7e + write(joinpath(dir, "$RootModule.jl"), + """ + module $RootModule + function f(x) + while x < 10 + x += oftype(x, 1) + end + return x + end + g1() = f(Int16(9)) + g2() = f(Int16(9)) + # all deliberately uncompiled + end + """) + RootA = :RootA_0xab07d60518763a7e + write(joinpath(dir, "$RootA.jl"), + """ + module $RootA + using $RootModule + fA() = $RootModule.f(Int8(4)) + fA() + $RootModule.g1() + end + """) + RootB = :RootB_0xab07d60518763a7e + write(joinpath(dir, "$RootB.jl"), + """ + module $RootB + using $RootModule + fB() = $RootModule.f(Int8(4)) + fB() + $RootModule.g2() + end + """) + Base.compilecache(Base.PkgId(string(RootA))) + Base.compilecache(Base.PkgId(string(RootB))) + @eval using $RootA + @eval using $RootB + MA = getfield(@__MODULE__, RootA) + MB = getfield(@__MODULE__, RootB) + M = getfield(MA, RootModule) + m = which(M.f, (Any,)) + for mi in m.specializations + mi === nothing && continue + if mi.specTypes.parameters[2] === Int8 + # external callers + mods = Module[] + for be in mi.backedges + push!(mods, be.def.module) + end + @test MA ∈ mods + @test MB ∈ mods + @test length(mods) == 2 + elseif mi.specTypes.parameters[2] === Int16 + # internal callers + meths = Method[] + for be in mi.backedges + push!(meths, be.def) + end + @test which(M.g1, ()) ∈ meths + @test which(M.g2, ()) ∈ meths + @test length(meths) == 2 + end + end + + # Invalidations (this test is adapted from from SnoopCompile) + function hasvalid(mi, world) + isdefined(mi, :cache) || return false + ci = mi.cache + while true + ci.max_world >= world && return true + isdefined(ci, :next) || return false + ci = ci.next + end + end + + StaleA = :StaleA_0xab07d60518763a7e + StaleB = :StaleB_0xab07d60518763a7e + StaleC = :StaleC_0xab07d60518763a7e + write(joinpath(dir, "$StaleA.jl"), + """ + module $StaleA + + stale(x) = rand(1:8) + stale(x::Int) = length(digits(x)) + + not_stale(x::String) = first(x) + + use_stale(c) = stale(c[1]) + not_stale("hello") + build_stale(x) = use_stale(Any[x]) + + # force precompilation + build_stale(37) + stale('c') + + end + """ + ) + write(joinpath(dir, "$StaleB.jl"), + """ + module $StaleB + + # StaleB does not know about StaleC when it is being built. + # However, if StaleC is loaded first, we get `"jl_insert_method_instance"` + # invalidations. + using $StaleA + + # This will be invalidated if StaleC is loaded + useA() = $StaleA.stale("hello") + + # force precompilation + useA() + + end + """ + ) + write(joinpath(dir, "$StaleC.jl"), + """ + module $StaleC + + using $StaleA + + $StaleA.stale(x::String) = length(x) + call_buildstale(x) = $StaleA.build_stale(x) + + call_buildstale("hey") + + end # module + """ + ) + for pkg in (StaleA, StaleB, StaleC) + Base.compilecache(Base.PkgId(string(pkg))) + end + @eval using $StaleA + @eval using $StaleC + @eval using $StaleB + MA = getfield(@__MODULE__, StaleA) + MB = getfield(@__MODULE__, StaleB) + MC = getfield(@__MODULE__, StaleC) + world = Base.get_world_counter() + m = only(methods(MA.use_stale)) + mi = m.specializations[1] + @test hasvalid(mi, world) # it was re-inferred by StaleC + m = only(methods(MA.build_stale)) + mis = filter(!isnothing, collect(m.specializations)) + @test length(mis) == 2 + for mi in mis + if mi.specTypes.parameters[2] == Int + @test mi.cache.max_world < world + else + # The variant for String got "healed" by recompilation in StaleC + @test mi.specTypes.parameters[2] == String + @test mi.cache.max_world == typemax(UInt) + end + end + m = only(methods(MB.useA)) + mi = m.specializations[1] + @test !hasvalid(mi, world) # invalidated by the stale(x::String) method in StaleC + m = only(methods(MC.call_buildstale)) + mi = m.specializations[1] + @test hasvalid(mi, world) # was compiled with the new method end # test --compiled-modules=no command line option From f9c76f0bcb2a26c8d96d878d1c480bf48b0460a0 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Mon, 28 Feb 2022 13:52:28 -0500 Subject: [PATCH 03/46] Add Pkg 1.8 news (#44370) --- NEWS.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/NEWS.md b/NEWS.md index b82e28130852f..caf9cd14a4568 100644 --- a/NEWS.md +++ b/NEWS.md @@ -111,6 +111,26 @@ Standard library changes * Intersect returns a result with the eltype of the type-promoted eltypes of the two inputs ([#41769]). * Iterating an `Iterators.Reverse` now falls back on reversing the eachindex iterator, if possible ([#43110]). +#### Package Manager + +* New `⌃` and `⌅` indicators beside packages in `pkg> status` that have new versions available. + `⌅` indicates when new versions cannot be installed ([Pkg#2906]). +* New `outdated::Bool` kwarg to `Pkg.status` (`--outdated` or `-o` in the REPL mode) to show + information about packages not at the latest version ([Pkg#2284]). +* New `compat::Bool` kwarg to `Pkg.status` (`--compat` or `-c` in the REPL mode) to show any [compat] + entries in the Project.toml ([Pkg#2702]). +* New `pkg> compat` (and `Pkg.compat`) mode for setting Project compat entries. Provides an interactive editor + via `pkg> compat`, or direct entry manipulation via `pkg> Foo 0.4,0.5` which can load current entries via tab-completion. + i.e. `pkg> compat Fo` autocompletes to `pkg> Foo 0.4,0.5` so that the existing entry can be edited ([Pkg#2702]). +* Pkg now only tries to download packages from the package server in case the server tracks a registry that contains + the package ([Pkg#2689]). +* `Pkg.instantiate` will now warn when a Project.toml is out of sync with a Manifest.toml. It does this by storing a hash + of the project deps and compat entries (other fields are ignored) in the manifest when it is resolved, so that any change + to the Project.toml deps or compat entries without a re-resolve can be detected ([Pkg#2815]). +* If `pkg> add` cannot find a package with the provided name it will now suggest similarly named packages that can be added ([Pkg#2985]). +* The julia version stored in the manifest no longer includes the build number i.e. master will now record as `1.9.0-DEV` ([Pkg#2995]). +* Interrupting a `pkg> test` will now be caught more reliably and exit back to the REPL gracefully ([Pkg#2933]). + #### InteractiveUtils * New macro `@time_imports` for reporting any time spent importing packages and their dependencies ([#41612]). @@ -211,6 +231,16 @@ Tooling Improvements * `GC.enable_logging(true)` can be used to log each garbage collection, with the time it took and the amount of memory that was collected ([#43511]). + + +[Pkg#2284]: https://github.com/JuliaLang/Pkg.jl/issues/2284 +[Pkg#2689]: https://github.com/JuliaLang/Pkg.jl/issues/2689 +[Pkg#2702]: https://github.com/JuliaLang/Pkg.jl/issues/2702 +[Pkg#2815]: https://github.com/JuliaLang/Pkg.jl/issues/2815 +[Pkg#2906]: https://github.com/JuliaLang/Pkg.jl/issues/2906 +[Pkg#2933]: https://github.com/JuliaLang/Pkg.jl/issues/2933 +[Pkg#2985]: https://github.com/JuliaLang/Pkg.jl/issues/2985 +[Pkg#2995]: https://github.com/JuliaLang/Pkg.jl/issues/2995 [#33711]: https://github.com/JuliaLang/julia/issues/33711 From 4857cd2e60de994074a92be0c2ed3510f360f25c Mon Sep 17 00:00:00 2001 From: Philip Tellis Date: Mon, 28 Feb 2022 15:52:39 -0500 Subject: [PATCH 04/46] Fix hyperlinks in 1.8 news (#44371) (cherry-picked from 675911a6ea263a4b0ec3654df9c84aec7285f027) --- NEWS.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index caf9cd14a4568..03ac98b71b198 100644 --- a/NEWS.md +++ b/NEWS.md @@ -17,7 +17,7 @@ New language features * `∀`, `∃`, and `∄` are now allowed as identifier characters ([#42314]). * Support for Unicode 14.0.0 ([#43443]). * `Module(:name, false, false)` can be used to create a `module` that contains no names - (it does not import `Base` or `Core` and does not contain a reference to itself) ([#40110, #42154]). + (it does not import `Base` or `Core` and does not contain a reference to itself) ([#40110], [#42154]). Language changes ---------------- @@ -250,6 +250,7 @@ Tooling Improvements [#38791]: https://github.com/JuliaLang/julia/issues/38791 [#39241]: https://github.com/JuliaLang/julia/issues/39241 [#39245]: https://github.com/JuliaLang/julia/issues/39245 +[#40110]: https://github.com/JuliaLang/julia/issues/40110 [#40382]: https://github.com/JuliaLang/julia/issues/40382 [#40642]: https://github.com/JuliaLang/julia/issues/40642 [#40783]: https://github.com/JuliaLang/julia/issues/40783 @@ -268,6 +269,7 @@ Tooling Improvements [#41794]: https://github.com/JuliaLang/julia/issues/41794 [#41888]: https://github.com/JuliaLang/julia/issues/41888 [#41936]: https://github.com/JuliaLang/julia/issues/41936 +[#42154]: https://github.com/JuliaLang/julia/issues/42154 [#42211]: https://github.com/JuliaLang/julia/issues/42211 [#42225]: https://github.com/JuliaLang/julia/issues/42225 [#42248]: https://github.com/JuliaLang/julia/issues/42248 From 3d8dadb9d8f7d8df1735337313970d02d4e0bfa9 Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Thu, 3 Mar 2022 05:36:37 -0600 Subject: [PATCH 05/46] Add NEWS on precompilation (#44325) --- NEWS.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/NEWS.md b/NEWS.md index 03ac98b71b198..4783338b4b525 100644 --- a/NEWS.md +++ b/NEWS.md @@ -54,6 +54,12 @@ Compiler/Runtime improvements Code heavily dependent on constant propagation should see significant compile-time performance improvements and certain cases (e.g. calls to uninlinable functions that are nevertheless effect free) should see runtime performance improvements. Effects may be overwritten manually with the `@Base.assume_effects` macro ([#43852]). +* Precompilation (with explicit `precompile` directives or representative workloads) now saves more type-inferred code, + resulting in reduced time-to-first task for packages that use precompilation. This change also eliminates the + runtime performance degradation occasionally triggered by precompilation on older Julia versions. More specifically, + any newly-inferred method/type combinations needed by your package--regardless of where those methods were + defined--can now be cached in the precompile file, as long as they are inferrably called by a method owned by + your package ([#43990]). Command-line option changes --------------------------- @@ -306,5 +312,6 @@ Tooling Improvements [#43852]: https://github.com/JuliaLang/julia/issues/43852 [#43865]: https://github.com/JuliaLang/julia/issues/43865 [#43919]: https://github.com/JuliaLang/julia/issues/43919 +[#43990]: https://github.com/JuliaLang/julia/issues/43990 [#44080]: https://github.com/JuliaLang/julia/issues/44080 [#44136]: https://github.com/JuliaLang/julia/issues/44136 From 5d3ebe0fa574b4ff47ee6a939f064331bc398f77 Mon Sep 17 00:00:00 2001 From: "Viral B. Shah" Date: Sat, 19 Feb 2022 17:13:58 -0500 Subject: [PATCH 06/46] Update LBT to 5.0.1 for source build (#44258) (cherry picked from commit 627016aaadc7c01f50f18bc9ff3fa40a02ce3f20) --- deps/blastrampoline.version | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deps/blastrampoline.version b/deps/blastrampoline.version index 86d77ab5bf293..23074f70854dc 100644 --- a/deps/blastrampoline.version +++ b/deps/blastrampoline.version @@ -1,2 +1,2 @@ -BLASTRAMPOLINE_BRANCH=v3.0.4 -BLASTRAMPOLINE_SHA1=23de7a09bf354fe6f655c457bab5bf47fdd2486d +BLASTRAMPOLINE_BRANCH=v5.0.1 +BLASTRAMPOLINE_SHA1=d32042273719672c6669f6442a0be5605d434b70 From 596d31f80152d31d74dd8acf5617ecdcb8f1a530 Mon Sep 17 00:00:00 2001 From: "Viral B. Shah" Date: Mon, 21 Feb 2022 10:04:07 -0500 Subject: [PATCH 07/46] Regenerate all the checksums (#44275) (cherry picked from commit ac922b0ad4295e13ec553abcab3b954e4a60064f) --- .../md5 | 1 - .../sha512 | 1 - deps/checksums/blastrampoline | 4 +- .../compiler-rt-11.0.1.src.tar.xz/md5 | 1 - .../compiler-rt-11.0.1.src.tar.xz/sha512 | 1 - deps/checksums/dsfmt | 4 +- deps/checksums/gmp | 58 ------------------- deps/checksums/libcxx-11.0.1.src.tar.xz/md5 | 1 - .../checksums/libcxx-11.0.1.src.tar.xz/sha512 | 1 - deps/checksums/lldb-11.0.1.src.tar.xz/md5 | 1 - deps/checksums/lldb-11.0.1.src.tar.xz/sha512 | 1 - deps/checksums/llvm | 34 ----------- deps/checksums/llvmunwind | 34 +++++++++++ deps/checksums/mpfr | 4 +- deps/checksums/pcre | 4 +- deps/checksums/zlib | 4 +- 16 files changed, 44 insertions(+), 110 deletions(-) delete mode 100644 deps/checksums/LibCURL-04c450c17024d5b49cb30013f1409306efd35203.tar.gz/md5 delete mode 100644 deps/checksums/LibCURL-04c450c17024d5b49cb30013f1409306efd35203.tar.gz/sha512 delete mode 100644 deps/checksums/compiler-rt-11.0.1.src.tar.xz/md5 delete mode 100644 deps/checksums/compiler-rt-11.0.1.src.tar.xz/sha512 delete mode 100644 deps/checksums/libcxx-11.0.1.src.tar.xz/md5 delete mode 100644 deps/checksums/libcxx-11.0.1.src.tar.xz/sha512 delete mode 100644 deps/checksums/lldb-11.0.1.src.tar.xz/md5 delete mode 100644 deps/checksums/lldb-11.0.1.src.tar.xz/sha512 create mode 100644 deps/checksums/llvmunwind diff --git a/deps/checksums/LibCURL-04c450c17024d5b49cb30013f1409306efd35203.tar.gz/md5 b/deps/checksums/LibCURL-04c450c17024d5b49cb30013f1409306efd35203.tar.gz/md5 deleted file mode 100644 index d10b369971129..0000000000000 --- a/deps/checksums/LibCURL-04c450c17024d5b49cb30013f1409306efd35203.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -6a545e3c5dc4a0d7fe73435ec4c45dea diff --git a/deps/checksums/LibCURL-04c450c17024d5b49cb30013f1409306efd35203.tar.gz/sha512 b/deps/checksums/LibCURL-04c450c17024d5b49cb30013f1409306efd35203.tar.gz/sha512 deleted file mode 100644 index 4f77a3abbb3c2..0000000000000 --- a/deps/checksums/LibCURL-04c450c17024d5b49cb30013f1409306efd35203.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -1308d4efde43eebd70646a77e4cf2d4a850a7c33d4a26018a1e84b4e7e1fb525ae193385fef7d47c405dbba0d685523d4b593702d93f441bcf8a495cc21fff0e diff --git a/deps/checksums/blastrampoline b/deps/checksums/blastrampoline index c0afa49764b87..d97f2fedd926b 100644 --- a/deps/checksums/blastrampoline +++ b/deps/checksums/blastrampoline @@ -1,5 +1,5 @@ -blastrampoline-23de7a09bf354fe6f655c457bab5bf47fdd2486d.tar.gz/md5/b81efa951fd909591339189f5909ff6b -blastrampoline-23de7a09bf354fe6f655c457bab5bf47fdd2486d.tar.gz/sha512/1c2558bab0aeaa76e7094d8a6a9798c95f2cf4efe2960640b70f1fd752f3dfb73813d9de93b539426376571febaab22ac22c2f903ccdf3296c7b067af92fecdc +blastrampoline-d32042273719672c6669f6442a0be5605d434b70.tar.gz/md5/f380e4238a2dec186ecfe9598f75b824 +blastrampoline-d32042273719672c6669f6442a0be5605d434b70.tar.gz/sha512/00437a96b57d99cef946257480e38e1dfdf325c46bc4a1619f5067565dfb7d9f668b0c8415badb0879b933cb1972f3c4e6be4c9e63a8a85728033e2183373819 libblastrampoline.v5.0.1+0.aarch64-apple-darwin.tar.gz/md5/8b2b28517ef5db95a0b440f1a936422e libblastrampoline.v5.0.1+0.aarch64-apple-darwin.tar.gz/sha512/3d479efc47b8c81fa85fd4d2a868a48304051432b92af90a2bcd2142673f2c422419731b8941f987aed429064532e8634ce3ea8f8d71222cf2d9b9e1e8ba2f7f libblastrampoline.v5.0.1+0.aarch64-linux-gnu.tar.gz/md5/23e53049a0c30c8d24482a25954ee497 diff --git a/deps/checksums/compiler-rt-11.0.1.src.tar.xz/md5 b/deps/checksums/compiler-rt-11.0.1.src.tar.xz/md5 deleted file mode 100644 index 0ad8aad90f820..0000000000000 --- a/deps/checksums/compiler-rt-11.0.1.src.tar.xz/md5 +++ /dev/null @@ -1 +0,0 @@ -29d6186e048936008512b8bbdb3a1b71 diff --git a/deps/checksums/compiler-rt-11.0.1.src.tar.xz/sha512 b/deps/checksums/compiler-rt-11.0.1.src.tar.xz/sha512 deleted file mode 100644 index 59f76a7d34acd..0000000000000 --- a/deps/checksums/compiler-rt-11.0.1.src.tar.xz/sha512 +++ /dev/null @@ -1 +0,0 @@ -869208f0d2c5f0828a317a6006d4ce47a946b03db2692c8557485caddc56fbeb0335a87b4c9663aa0d1397de94337e56ae10f802c4aca443072962f728e2bdf4 diff --git a/deps/checksums/dsfmt b/deps/checksums/dsfmt index 12d071b1fab2b..edadf5c01b1d7 100644 --- a/deps/checksums/dsfmt +++ b/deps/checksums/dsfmt @@ -1,5 +1,3 @@ -dsfmt-2.2.4.tar.gz/md5/ed30e63552d62df48d709dde4f755660 -dsfmt-2.2.4.tar.gz/sha512/fe84e986cbf198172340adfac0436b08f087643eca3f1ceccacde146cbfd8c41e3eb0dfbb062f7ca5f462db13c386abd7c269bc0cbefc9a0ecf97a8a8870a2e4 dSFMT.v2.2.4+1.aarch64-apple-darwin.tar.gz/md5/0299af20dae6bed519635900687f4aeb dSFMT.v2.2.4+1.aarch64-apple-darwin.tar.gz/sha512/5f20bd7602f09dcb23299d979372453db9a0e76a66129d69cc93c4b45a65ad377486f3cecb7093ff65307f515358420dc318b19eaf5945ff2fbfbe6886e95efa dSFMT.v2.2.4+1.aarch64-linux-gnu.tar.gz/md5/78a0fa53ad3db17f2849c744246a6bc6 @@ -32,3 +30,5 @@ dSFMT.v2.2.4+1.x86_64-unknown-freebsd.tar.gz/md5/e27869ac4f1ea6774ade7d3b53cd301 dSFMT.v2.2.4+1.x86_64-unknown-freebsd.tar.gz/sha512/762571a5d5773c2d9780586603859272f48ed67d6c8b09cd95c92fd62dc9bb03c274b12c2c04e05f426c9a42edbbc8e33beba3c79865f2c49459eca2d588b14c dSFMT.v2.2.4+1.x86_64-w64-mingw32.tar.gz/md5/74e5c27ba9eb654b4e998ce73719e724 dSFMT.v2.2.4+1.x86_64-w64-mingw32.tar.gz/sha512/59badcef14b06f14f8f5bce1c72de6750c8310ae18581e24b5d663edefe1bed3d120b4cebb87b53dc664411b62d9802f75aefde4e5236ada1dec740e6ef2445d +dsfmt-2.2.4.tar.gz/md5/ed30e63552d62df48d709dde4f755660 +dsfmt-2.2.4.tar.gz/sha512/fe84e986cbf198172340adfac0436b08f087643eca3f1ceccacde146cbfd8c41e3eb0dfbb062f7ca5f462db13c386abd7c269bc0cbefc9a0ecf97a8a8870a2e4 diff --git a/deps/checksums/gmp b/deps/checksums/gmp index 6b95ca883ddf8..47cee2e34a42f 100644 --- a/deps/checksums/gmp +++ b/deps/checksums/gmp @@ -1,61 +1,3 @@ -GMP.v6.2.1+0.aarch64-apple-darwin.tar.gz/md5/e805c580078e4d6bcaeb6781cb6d56fa -GMP.v6.2.1+0.aarch64-apple-darwin.tar.gz/sha512/62435e80f5fa0b67e2788c8bfc3681426add7a9b2853131bbebe890d1a2d9b54cebaea0860f6ddd0e93e1ae302baba39851d5f58a65acf0b2a9ea1226bb4eea4 -GMP.v6.2.1+0.aarch64-linux-gnu-cxx03.tar.gz/md5/5384d6ba6fd408bc71c2781b643cd59a -GMP.v6.2.1+0.aarch64-linux-gnu-cxx03.tar.gz/sha512/99bdf165b44b53605bd3121a741ca4576c4dd37861f4e2e2f3b508c1a797855ba8647c98f24ded875a1dc55ec577d4f617620c05606b4d2cf04361c143b818e7 -GMP.v6.2.1+0.aarch64-linux-gnu-cxx11.tar.gz/md5/67641c0755a252965fc842d0f55ea24d -GMP.v6.2.1+0.aarch64-linux-gnu-cxx11.tar.gz/sha512/a7db5855898adad99b2d36fce5d8db5b1aaccf47d5fc419c6c52c838a68ae374e49f76424807c351213ee5339acf2bdd31b38de9b75bb826b6c6a37c48c6f12c -GMP.v6.2.1+0.aarch64-linux-musl-cxx03.tar.gz/md5/49377ccee261d425e9fb6d7716776742 -GMP.v6.2.1+0.aarch64-linux-musl-cxx03.tar.gz/sha512/9e8c92c86dd98e339691796362d8a70d51e07d7ba78cc48455ee15243f9df84030ba5cc3080a200a6e94e0c002a7517e702570cc6e6d38301e90f991556cb090 -GMP.v6.2.1+0.aarch64-linux-musl-cxx11.tar.gz/md5/cd4cb308ae7736ea91ec5b97b7c80923 -GMP.v6.2.1+0.aarch64-linux-musl-cxx11.tar.gz/sha512/d84f399b8e66d5d86abcbfb30ba23a1676f5a469e8cde6b316322889ca0a242533bb537bb3cb5c57407dc9d91ce9f3cf879f71bddaf2fdef08b103e30674ec39 -GMP.v6.2.1+0.armv6l-linux-gnueabihf-cxx03.tar.gz/md5/c115f3f1e1575649e8c898336cfb6300 -GMP.v6.2.1+0.armv6l-linux-gnueabihf-cxx03.tar.gz/sha512/3443d0994b625adb2c4bb013618372aff82de1c54022c45c7bf1bd043fbda6f50a4202018066569572a3ef8bb90725055628e1295b454dd56951b408d67c2f56 -GMP.v6.2.1+0.armv6l-linux-gnueabihf-cxx11.tar.gz/md5/c80eb461a5427bc83ed38a2b15a6a354 -GMP.v6.2.1+0.armv6l-linux-gnueabihf-cxx11.tar.gz/sha512/3bcecb52ad64e587d50a6bdbc19560cd961360b265403639662b9314806e394848e64bd9d2be6881a3467f4c42ab43872035f71d5a0421f3284e5e08ad4cccb3 -GMP.v6.2.1+0.armv6l-linux-musleabihf-cxx03.tar.gz/md5/14f0a09730eda4706b64042c4eb204b0 -GMP.v6.2.1+0.armv6l-linux-musleabihf-cxx03.tar.gz/sha512/c405065dba56aaafeee907baaec3e23337ccdc67f2cdfc460b6d5c338e85b0ec211f39df67a885fa5048d444ad28a07207ecc31872888576fbaec0c2881a2240 -GMP.v6.2.1+0.armv6l-linux-musleabihf-cxx11.tar.gz/md5/14b8bd2136680d00261264876da76f34 -GMP.v6.2.1+0.armv6l-linux-musleabihf-cxx11.tar.gz/sha512/f6b5f56af796bd0e9411eabc53864c773002ba5fee44398770260cd1a0114ce9a1e0d3531f424f968e16436fb9f51e31b896fa3f43277405fe759141093d556d -GMP.v6.2.1+0.armv7l-linux-gnueabihf-cxx03.tar.gz/md5/cfa020ab9b1f0d9f761034ce28acd851 -GMP.v6.2.1+0.armv7l-linux-gnueabihf-cxx03.tar.gz/sha512/2678b9b45a065569c58ed840bb5b0f5fb1a1e59897fa7054738760aba737b11f1d180f632f3f04a80a5530463b005367e41f4c599526abc688e86cd9a032888e -GMP.v6.2.1+0.armv7l-linux-gnueabihf-cxx11.tar.gz/md5/8b238ae87be9b3ee908044b5dbd295da -GMP.v6.2.1+0.armv7l-linux-gnueabihf-cxx11.tar.gz/sha512/4e91356b3a294f1eec4309e6db0d9160edd5afe3d3cac6b8211853ff179642504669c403e8e6053accf187d86d55a7700db64e870c6321484247cc0648e4e793 -GMP.v6.2.1+0.armv7l-linux-musleabihf-cxx03.tar.gz/md5/fe1c989a71b4a292f96c410b8b467834 -GMP.v6.2.1+0.armv7l-linux-musleabihf-cxx03.tar.gz/sha512/b87d0e869cafa27d5b229025b23b081051b25a38291128290fb15f18f5445129ff7b9a74c3076da011e503463521128c5940677e8290e6e15c7a57e92916be2e -GMP.v6.2.1+0.armv7l-linux-musleabihf-cxx11.tar.gz/md5/47323b44eb6f0b1342500cb38943923a -GMP.v6.2.1+0.armv7l-linux-musleabihf-cxx11.tar.gz/sha512/11bf94c7df9aadbbb01b83628967c110bf9bbfee68ae9f7792ba2aeb004e555c50ed54974f0a56525eb43555a9de955003ff66283979e02724bd577c73b1e855 -GMP.v6.2.1+0.i686-linux-gnu-cxx03.tar.gz/md5/0b8ad9c99dec6097ecad2f7e8946014d -GMP.v6.2.1+0.i686-linux-gnu-cxx03.tar.gz/sha512/29dc39445cc89e156866c7607bace3e61a18348d3772b5f354cdef2b57e6c1c8be1682b1705f5bfa9314c973a7592db9dfc9027f0cf2ad12c935e876c3845052 -GMP.v6.2.1+0.i686-linux-gnu-cxx11.tar.gz/md5/f8ce89edd1412fd54b98c1c85870ecee -GMP.v6.2.1+0.i686-linux-gnu-cxx11.tar.gz/sha512/add5da0d9b5b1cd66192fad3028203114fcf4908d3bd24e6d13fb59d85c4413f82cbde917d6bbc9f80186da54627531680ccf53146b9c0262523c29192a1ac85 -GMP.v6.2.1+0.i686-linux-musl-cxx03.tar.gz/md5/84c1f2487a10daab9b715d9cc490253b -GMP.v6.2.1+0.i686-linux-musl-cxx03.tar.gz/sha512/fb4a2f27a932273e1f2dabfe31c02d96892d3767c9cc488ade254dc05fe0bb1d9894b4e7afc72a7b9928f05b26bbb4eec05df71aaa15c8d99bc050e64f725663 -GMP.v6.2.1+0.i686-linux-musl-cxx11.tar.gz/md5/5fb602b9d2a80aa041fdd9a7f01b0827 -GMP.v6.2.1+0.i686-linux-musl-cxx11.tar.gz/sha512/f51dd2c914c4957052502ff32bb185115f9950a42d20e3443040574ab84ae929ad04f2e53ca5296803f726182c71438156b7f8691c50d3450824693579fd0e4a -GMP.v6.2.1+0.i686-w64-mingw32-cxx03.tar.gz/md5/c03aad92ce6d66b1a795f7213b0ff9f0 -GMP.v6.2.1+0.i686-w64-mingw32-cxx03.tar.gz/sha512/97789b371cb66699fc26e32f658020f0dd9fb4242bc2253be5ccee91e0cda8bfe393b8c57c4bf3ee2ae5c585fd79ad42a48c058c0c02491358680b9acb197137 -GMP.v6.2.1+0.i686-w64-mingw32-cxx11.tar.gz/md5/23a32a01e4fa9e34ff72773c913f4cb3 -GMP.v6.2.1+0.i686-w64-mingw32-cxx11.tar.gz/sha512/1a1569eb095d9cb1c697a488cd57dce9d4a96447d19a94dfa95f03f47b91c2cee676f0fbdf313062019eabe4b6ce28d6c5978f53c9fb537ee6e9c39530bb9529 -GMP.v6.2.1+0.powerpc64le-linux-gnu-cxx03.tar.gz/md5/98e4b7257714395e6a64848381187fb1 -GMP.v6.2.1+0.powerpc64le-linux-gnu-cxx03.tar.gz/sha512/a8775f0f7d2c0f0511fee0fdacbc60e68dbb4dc92a787849516fd9ae01289dfcf2c5b60e2999568e3374e386f6708adc6d3d17b07bc0345f8ed4e3eb00a1e072 -GMP.v6.2.1+0.powerpc64le-linux-gnu-cxx11.tar.gz/md5/dff490a43ca1d6974c43f2d9356c6c54 -GMP.v6.2.1+0.powerpc64le-linux-gnu-cxx11.tar.gz/sha512/557f706464ae636e2720e4483ee4e20d83267f5824ee5c963cf75270d8b76ce8f5c3a1ddc8fbca6ade8d044bfb2e125e19ca43452277a24e6991a6aaf5b4d1f5 -GMP.v6.2.1+0.x86_64-apple-darwin.tar.gz/md5/80a9cf52964de5e9ecca4d4e86606e72 -GMP.v6.2.1+0.x86_64-apple-darwin.tar.gz/sha512/06d4ce5343ab9809908295cc322e0186b5b4cd94b67fbb17d5c648a7f5ed219eb15b8a4bbac2035c078e66eda80b412bb630fff1a9bf60722ba23526e0dfbb9c -GMP.v6.2.1+0.x86_64-linux-gnu-cxx03.tar.gz/md5/a0e34e7eb8dc0a45fa7a746d5077d8f7 -GMP.v6.2.1+0.x86_64-linux-gnu-cxx03.tar.gz/sha512/ae6f052766ffe8e9595ce78d8ad8589459456801910b78321fbd174b095a6822ec046ca69ec9496f0ee676312e7008ca7e9b179890c586672eeab817c8da67b3 -GMP.v6.2.1+0.x86_64-linux-gnu-cxx11.tar.gz/md5/a444271a5a3fb646a1bf3071b4b58109 -GMP.v6.2.1+0.x86_64-linux-gnu-cxx11.tar.gz/sha512/a756425aa4d67cd8822f2fb23d055b455787ed1339f1995f9bbf905021d041dd663ddafd1c681a35bc5e124ce6acbb69789ae483ed7168c9fb8a6bf1bc9c144a -GMP.v6.2.1+0.x86_64-linux-musl-cxx03.tar.gz/md5/1aa292bffef8ebe685e4486513c0cbef -GMP.v6.2.1+0.x86_64-linux-musl-cxx03.tar.gz/sha512/03968755c53457296b79752ca9808d4660aad8474f876836cec9e9d6c1c38267614a134bd222a50eddac5dddbe923df3a4d11298bd1e019876b717033ffd3eb3 -GMP.v6.2.1+0.x86_64-linux-musl-cxx11.tar.gz/md5/ef269f501c1a331ef6c3e7905047c3eb -GMP.v6.2.1+0.x86_64-linux-musl-cxx11.tar.gz/sha512/9c58c2fc09ec6f5e8e21602fdc22ca49c4b54ed1bbf544717c376a1d67b378cd63b9f25c1a8e3e12c358783eba17662b1a6b661ca5f588655e8b6ecbf490e199 -GMP.v6.2.1+0.x86_64-unknown-freebsd.tar.gz/md5/54b35608d79a2bc3f9d81be8cd8fe7a3 -GMP.v6.2.1+0.x86_64-unknown-freebsd.tar.gz/sha512/79aa5e7705aad4b4d5d248d0bef3ab1d17185ce710058a8f3e74e5eab86190a9150d316eb3a33ae41a497f3a94da03f90768978f2e154c5db57f5345bf0ba4c9 -GMP.v6.2.1+0.x86_64-w64-mingw32-cxx03.tar.gz/md5/1499a265b438cf5169286c1830eb5734 -GMP.v6.2.1+0.x86_64-w64-mingw32-cxx03.tar.gz/sha512/d2e6fe76abe0a0cb1a7445ea93cd5bd0bf9f729aec8df9c76d06a1f6f5e67cce442be69b66950eb33aa22cfda2e5a308f2bade64018a27bebfcb4b7a97e1d047 -GMP.v6.2.1+0.x86_64-w64-mingw32-cxx11.tar.gz/md5/fdb4187f617511d8eb19f67f8499a8d0 -GMP.v6.2.1+0.x86_64-w64-mingw32-cxx11.tar.gz/sha512/bb6d8ead1c20cffebc2271461d3787cfad794fee2b32e23583af6521c0667ed9107805268a996d23d6edcab9fe653e542a210cab07252f7713af0c23feb76fb3 GMP.v6.2.1+1.aarch64-apple-darwin.tar.gz/md5/03cb14ac16daabb4a77fe1c78e8e48a9 GMP.v6.2.1+1.aarch64-apple-darwin.tar.gz/sha512/5b8f974a07f579272981f5ebe44191385a4ce95f58d434a3565ffa827a6d65824cbe4173736b7328630bbccfe6af4242195aec24de3f0aa687e2e32a18a97a5c GMP.v6.2.1+1.aarch64-linux-gnu-cxx03.tar.gz/md5/0ce7d419a49f2f90033618bdda2588e7 diff --git a/deps/checksums/libcxx-11.0.1.src.tar.xz/md5 b/deps/checksums/libcxx-11.0.1.src.tar.xz/md5 deleted file mode 100644 index 5b905de3304cc..0000000000000 --- a/deps/checksums/libcxx-11.0.1.src.tar.xz/md5 +++ /dev/null @@ -1 +0,0 @@ -4b2467eb023c9b4c84335808f811d5fa diff --git a/deps/checksums/libcxx-11.0.1.src.tar.xz/sha512 b/deps/checksums/libcxx-11.0.1.src.tar.xz/sha512 deleted file mode 100644 index 251c002b1e83d..0000000000000 --- a/deps/checksums/libcxx-11.0.1.src.tar.xz/sha512 +++ /dev/null @@ -1 +0,0 @@ -adda227d412bc28a47612cc6580bf85353838792b4816633d8401efb92cd65f6801278941f779d301bd6162b75ef8d54825f9cdfb0f61c6f5f621eca7fb7c004 diff --git a/deps/checksums/lldb-11.0.1.src.tar.xz/md5 b/deps/checksums/lldb-11.0.1.src.tar.xz/md5 deleted file mode 100644 index 901bdea38188d..0000000000000 --- a/deps/checksums/lldb-11.0.1.src.tar.xz/md5 +++ /dev/null @@ -1 +0,0 @@ -e49cde09adb5ed43a651e6d5bcb2aded diff --git a/deps/checksums/lldb-11.0.1.src.tar.xz/sha512 b/deps/checksums/lldb-11.0.1.src.tar.xz/sha512 deleted file mode 100644 index 16f939fb1007e..0000000000000 --- a/deps/checksums/lldb-11.0.1.src.tar.xz/sha512 +++ /dev/null @@ -1 +0,0 @@ -05de84a0606becdabacb46fbc5cd67607ca47c22469da13470b76a96b96e6f34b3045fd1f5bed9c82228c2ce529562ee71667788a5048f079fef450d63a1557c diff --git a/deps/checksums/llvm b/deps/checksums/llvm index cff2c009bd0ce..6cb85ecdc0d3b 100644 --- a/deps/checksums/llvm +++ b/deps/checksums/llvm @@ -56,38 +56,6 @@ LLVM.v13.0.1+0.x86_64-w64-mingw32-cxx03.tar.gz/md5/1823541a9a6c9e9134ac764550139 LLVM.v13.0.1+0.x86_64-w64-mingw32-cxx03.tar.gz/sha512/2dbee2c1f01e5cc4f0b70c0147352ad95f0b91f5cb1efcde7ed61b54b2baa1b0bcea0b97e0c0ff6c55526e6b037f25808cf995f861ce46da56195bfe0b0e48e3 LLVM.v13.0.1+0.x86_64-w64-mingw32-cxx11.tar.gz/md5/454453a2afb04e3c4d6cdffb37591a3d LLVM.v13.0.1+0.x86_64-w64-mingw32-cxx11.tar.gz/sha512/21bda5f9ceb9d4030121eb9c563233bcdab5b9d1d5b0b9b0fd22cfba3d507ec59ab4c98211d0d5c2cc5ac0b0695d1fbe4707a0264fde423833cd7a461193b556 -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 LLVM_assert.v13.0.1+0.aarch64-apple-darwin.tar.gz/md5/edbc793469fb7c14af3c33f8584d22df LLVM_assert.v13.0.1+0.aarch64-apple-darwin.tar.gz/sha512/a3137f2d2d4847e6db1acfc834e686379cdd80712feb3d36d616f73af473599356ade48c98a865d3c233a59d395d40114083fbd78617001b95ebe363fe12cde5 LLVM_assert.v13.0.1+0.aarch64-linux-gnu-cxx03.tar.gz/md5/00176b5cd73dea5f9265155574c08dd5 @@ -264,5 +232,3 @@ libLLVM_assert.v13.0.1+0.x86_64-w64-mingw32-cxx11.tar.gz/md5/a458b0572d77d3d79b6 libLLVM_assert.v13.0.1+0.x86_64-w64-mingw32-cxx11.tar.gz/sha512/43b6ab2becd9b3179f91f2f856854d4795e53c4078dda26607e5b6a8dfde37cdc28f9fec6c0ca9e0d0d8de5f2304d5775d5c6b7a03c0f6feb2b93e43053997c4 llvm-julia-13.0.1-0.tar.gz/md5/34edc9f707d86fe8c5758b0ae8c35206 llvm-julia-13.0.1-0.tar.gz/sha512/0d55c1bf3c581551faa077aab7046d1f020e8775ed16f1fbd8ccee65bc8f43173504f5ce1215227fa5e565f2804f8772e2cda039bc333bb23677067a4a3f9f87 -llvmunwind-12.0.1.tar.xz/md5/4ec327cee517fdb1f6a20e83748e2c7b -llvmunwind-12.0.1.tar.xz/sha512/847b6ba03010a43f4fdbfdc49bf16d18fd18474d01584712e651b11191814bf7c1cf53475021d9ee447ed78413202b4ed97973d7bdd851d3e49f8d06f55a7af4 diff --git a/deps/checksums/llvmunwind b/deps/checksums/llvmunwind new file mode 100644 index 0000000000000..678ae7b0c3fc4 --- /dev/null +++ b/deps/checksums/llvmunwind @@ -0,0 +1,34 @@ +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 +llvmunwind-12.0.1.tar.xz/md5/4ec327cee517fdb1f6a20e83748e2c7b +llvmunwind-12.0.1.tar.xz/sha512/847b6ba03010a43f4fdbfdc49bf16d18fd18474d01584712e651b11191814bf7c1cf53475021d9ee447ed78413202b4ed97973d7bdd851d3e49f8d06f55a7af4 diff --git a/deps/checksums/mpfr b/deps/checksums/mpfr index 8353d49aa190b..0eb73ceb693a2 100644 --- a/deps/checksums/mpfr +++ b/deps/checksums/mpfr @@ -1,5 +1,3 @@ -mpfr-4.1.0.tar.bz2/md5/44b892bc5a45bafb4294d134e13aad1d -mpfr-4.1.0.tar.bz2/sha512/410208ee0d48474c1c10d3d4a59decd2dfa187064183b09358ec4c4666e34d74383128436b404123b831e585d81a9176b24c7ced9d913967c5fce35d4040a0b4 MPFR.v4.1.1+1.aarch64-apple-darwin.tar.gz/md5/157265257536980394e0a025b9d28de1 MPFR.v4.1.1+1.aarch64-apple-darwin.tar.gz/sha512/44064eb67f087c2c38857273b069eacec9ebc199dd908f975895ab28bcdeb761adaec1a20cb5c3a98788090eb9ec31678ab1c5802896b22738d120e379f1f6ad MPFR.v4.1.1+1.aarch64-linux-gnu.tar.gz/md5/ed45c58b6f9ee6993f34012570ffa6bd @@ -32,3 +30,5 @@ MPFR.v4.1.1+1.x86_64-unknown-freebsd.tar.gz/md5/9dc9d9bb0662700510b89e6da4f44f2d MPFR.v4.1.1+1.x86_64-unknown-freebsd.tar.gz/sha512/14208fb683233d44eb2263e7674b9c5cf4f7f7151f025b2b00fb482e6609b78b2189eb25edd7c45b8634bca07e1aca746a6094af50d1449248847529ff58bcaa MPFR.v4.1.1+1.x86_64-w64-mingw32.tar.gz/md5/6159f631081b32b7df88e090af417f4c MPFR.v4.1.1+1.x86_64-w64-mingw32.tar.gz/sha512/5086da1de24b1f9431ea7dbe6407ae9c81df7a10b04845e8fe4a476a6a5dcb78d3e4b06ca81c85d1a8cf2d081948d20bb77672a4c9f6d20e194f384a323a1f71 +mpfr-4.1.0.tar.bz2/md5/44b892bc5a45bafb4294d134e13aad1d +mpfr-4.1.0.tar.bz2/sha512/410208ee0d48474c1c10d3d4a59decd2dfa187064183b09358ec4c4666e34d74383128436b404123b831e585d81a9176b24c7ced9d913967c5fce35d4040a0b4 diff --git a/deps/checksums/pcre b/deps/checksums/pcre index f7e1fa0c1a3ba..05a06f9844ddf 100644 --- a/deps/checksums/pcre +++ b/deps/checksums/pcre @@ -1,5 +1,3 @@ -pcre2-10.36.tar.bz2/md5/bd7e7421ff3fa2e2d5429229ecfad095 -pcre2-10.36.tar.bz2/sha512/fc2a920562c80c3d31cedd94028fab55314ae0fb168cac7178f286c344a11fc514939edc3b83b8e0b57c872db4e595fd5530fd1d4b8c779be629553e9ec965a3 PCRE2.v10.36.0+2.aarch64-apple-darwin.tar.gz/md5/12ac3bee39df3a79f868f6463964953b PCRE2.v10.36.0+2.aarch64-apple-darwin.tar.gz/sha512/a1a1312931deb7f742f80886188babcf9c179ed3f156626fb23d92633fde896d1ee9b2d72cd99ae4a1f8048971b6d939e9b0b10c455d4eeec24b265968593486 PCRE2.v10.36.0+2.aarch64-linux-gnu.tar.gz/md5/32240ccddee3040aeedcbe69ea52fcad @@ -32,3 +30,5 @@ PCRE2.v10.36.0+2.x86_64-unknown-freebsd.tar.gz/md5/97410029c0b6ed5f7fb0d14e1f121 PCRE2.v10.36.0+2.x86_64-unknown-freebsd.tar.gz/sha512/229e910759da2959ddef83ca89e05a050c266b8e755c85dfce6a786658be541911c3b78a0fca7dfdee1b41fbbdccf57da75cf9fe45fd2821dba8d2aaeabfd538 PCRE2.v10.36.0+2.x86_64-w64-mingw32.tar.gz/md5/39827564bca329768e0380bd79b869fe PCRE2.v10.36.0+2.x86_64-w64-mingw32.tar.gz/sha512/4579049b99fca3334d726b0ca1f07524d1643a758e375b5b02b8f294ba7d9c2a4130da1a1523de29033233a8848105b3cb660e15bb4a759593405d805ee99883 +pcre2-10.36.tar.bz2/md5/bd7e7421ff3fa2e2d5429229ecfad095 +pcre2-10.36.tar.bz2/sha512/fc2a920562c80c3d31cedd94028fab55314ae0fb168cac7178f286c344a11fc514939edc3b83b8e0b57c872db4e595fd5530fd1d4b8c779be629553e9ec965a3 diff --git a/deps/checksums/zlib b/deps/checksums/zlib index ba31ecdbae00b..6b14164c8318f 100644 --- a/deps/checksums/zlib +++ b/deps/checksums/zlib @@ -1,5 +1,3 @@ -zlib-cacf7f1d4e3d44d871b605da3b647f07d718623f.tar.gz/md5/93d10d4dd040f14ae63417070d1346e8 -zlib-cacf7f1d4e3d44d871b605da3b647f07d718623f.tar.gz/sha512/a1e9c5a2963266a582192d0fe88c179f5239245f11c4df4427dda755ad77d31e1fcf045d7d3fe49141090f4ff8da13d9a2e8d8d317fe6460a5f3e9bdea29b883 Zlib.v1.2.12+1.aarch64-apple-darwin.tar.gz/md5/6e255e13279855a99dae7d4ccf206069 Zlib.v1.2.12+1.aarch64-apple-darwin.tar.gz/sha512/d160928dc6cad6bbc9fce36ea0d807c1f432aae375e6a032b0fd58d18640d02fc50c25233b32f8b73f3fc3488a091cf57418ad04498160441e3d7e4aa79302fe Zlib.v1.2.12+1.aarch64-linux-gnu.tar.gz/md5/ff0ce9d6dec1c1b07114ed48f2bcfc88 @@ -32,3 +30,5 @@ Zlib.v1.2.12+1.x86_64-unknown-freebsd.tar.gz/md5/21dfda8d26dbe76c914216e79d7847d Zlib.v1.2.12+1.x86_64-unknown-freebsd.tar.gz/sha512/2cd7be4070dbf20ab1c46553a9e3f84c98bf8e8fc72bf2eb4678630e648cb9ad02cae5e004f3c2a69216e2782d9bba43eac6a45a480f6fe58d1091a9fbba93ff Zlib.v1.2.12+1.x86_64-w64-mingw32.tar.gz/md5/140ddbeeaf27867aeeeec118682e879d Zlib.v1.2.12+1.x86_64-w64-mingw32.tar.gz/sha512/f61f3d1eb7e7960b2fdbc1d68f22526a06ba598cd821261e7ba3819e00daee4c5b5427f9c03277b57b7226860142f0071410c0583535ca4e4b9acbe5ee4b5ade +zlib-cacf7f1d4e3d44d871b605da3b647f07d718623f.tar.gz/md5/93d10d4dd040f14ae63417070d1346e8 +zlib-cacf7f1d4e3d44d871b605da3b647f07d718623f.tar.gz/sha512/a1e9c5a2963266a582192d0fe88c179f5239245f11c4df4427dda755ad77d31e1fcf045d7d3fe49141090f4ff8da13d9a2e8d8d317fe6460a5f3e9bdea29b883 From 3f28e07fe15c2bca06aae1b6be883d309a5da66e Mon Sep 17 00:00:00 2001 From: "Viral B. Shah" Date: Tue, 22 Feb 2022 22:36:20 -0500 Subject: [PATCH 08/46] Documentation: added example to the function hasfield. (From #41782) (#44274) Co-authored-by: Johnny Chen (cherry picked from commit 9c0e5b0d186ea95a06d5b0bdc4bc19d1a17b444d) (cherry picked from commit aa2421dc99544542c816b7c8e8add727673767d3) --- base/reflection.jl | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/base/reflection.jl b/base/reflection.jl index bf8ceabe1f39b..5490cae9511c8 100644 --- a/base/reflection.jl +++ b/base/reflection.jl @@ -194,8 +194,23 @@ fieldnames(t::Type{<:Tuple}) = ntuple(identity, fieldcount(t)) Return a boolean indicating whether `T` has `name` as one of its own fields. +See also [`fieldnames`](@ref), [`fieldcount`](@ref), [`hasproperty`](@ref). + !!! compat "Julia 1.2" This function requires at least Julia 1.2. + +# Examples +```jldoctest +julia> struct Foo + bar::Int + end + +julia> hasfield(Foo, :bar) +true + +julia> hasfield(Foo, :x) +false +``` """ function hasfield(T::Type, name::Symbol) @_pure_meta From acbb1f6f74d3df27344a1a40468ee6ffae3f646c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mos=C3=A8=20Giordano?= Date: Thu, 24 Feb 2022 18:36:07 +0000 Subject: [PATCH 09/46] [OpenBLAS_jll] Update to v0.3.20 (#44321) (cherry picked from commit 6850940b8115ec6ee0ba9a7cd20185196620b097) --- deps/checksums/openblas | 188 +++++++++--------- deps/openblas.mk | 7 +- deps/openblas.version | 4 +- ...as-julia42415-lapack625-openblas3392.patch | 95 --------- deps/patches/openblas-ofast-power.patch | 19 +- stdlib/OpenBLAS_jll/Project.toml | 2 +- 6 files changed, 108 insertions(+), 207 deletions(-) delete mode 100644 deps/patches/openblas-julia42415-lapack625-openblas3392.patch diff --git a/deps/checksums/openblas b/deps/checksums/openblas index 31e6e27d61d20..1523372d709fa 100644 --- a/deps/checksums/openblas +++ b/deps/checksums/openblas @@ -1,94 +1,94 @@ -OpenBLAS.v0.3.17+2.aarch64-apple-darwin-libgfortran5.tar.gz/md5/9020e93ed6349bab95c2ca7cf21b2ebf -OpenBLAS.v0.3.17+2.aarch64-apple-darwin-libgfortran5.tar.gz/sha512/3058c47b1fecc9d9d63dee30d277fbe665b3641850e72349415c18dc8372971c3f1c36c9cf62ceec672604e70f5b5a0c118e484f63aaf1aba37075324537908b -OpenBLAS.v0.3.17+2.aarch64-linux-gnu-libgfortran3.tar.gz/md5/02f560828fab7c2df6ce7d81927045ed -OpenBLAS.v0.3.17+2.aarch64-linux-gnu-libgfortran3.tar.gz/sha512/54f9acd7842ad8305073dde0e0e689a35e79cdee8f843560091fa3277957b9ca298d1516d027c6f0870d48743a70285714fec4f09e0eb43bd6954e8d6bea3843 -OpenBLAS.v0.3.17+2.aarch64-linux-gnu-libgfortran4.tar.gz/md5/24f4d8eea07a992735fc4433d24cdd74 -OpenBLAS.v0.3.17+2.aarch64-linux-gnu-libgfortran4.tar.gz/sha512/8e1fb731cb9e3e0a9214c01538b2974eb6ed1a69857327e29dd166719491015d9a0695a75100ec804a5f9beaec121cc095f1ddf8c7a417f18a046035f1969c06 -OpenBLAS.v0.3.17+2.aarch64-linux-gnu-libgfortran5.tar.gz/md5/de3d9d1bd4b8d148084499f97ef9eff3 -OpenBLAS.v0.3.17+2.aarch64-linux-gnu-libgfortran5.tar.gz/sha512/d7d31bc345389c5240a5dc7341741264ea328adc3604c8fea3e21914c13c3a1720270427465daccdfce080d2df6723384d2d9e9907db2a24c8fde32e492ccae4 -OpenBLAS.v0.3.17+2.aarch64-linux-musl-libgfortran3.tar.gz/md5/665a8dd827b32769fd307f65f18ce09f -OpenBLAS.v0.3.17+2.aarch64-linux-musl-libgfortran3.tar.gz/sha512/070d015f72d0030838985e949f1855e40997fcf31e1c51a1cc5666d681cb47fb02a289435cebd8ef15346bcb85140b0e164874dcf9e269e8799253fb538ea3f7 -OpenBLAS.v0.3.17+2.aarch64-linux-musl-libgfortran4.tar.gz/md5/fe47ac70b33442c9c7d882ea87e86901 -OpenBLAS.v0.3.17+2.aarch64-linux-musl-libgfortran4.tar.gz/sha512/d97588cb9511225e160fd6fc828a13e8f99ca6e16ecdbf57bc8e7a95296c004ca11316854f90421cf0ac7935a7ec09045324af2de6084b11c62dcdc3e96d1249 -OpenBLAS.v0.3.17+2.aarch64-linux-musl-libgfortran5.tar.gz/md5/fd550b91aec55ed97c86c876f2339edd -OpenBLAS.v0.3.17+2.aarch64-linux-musl-libgfortran5.tar.gz/sha512/53c258962bff09e8a4642c6bd02949792e36b7681bad45b3d21b711428025262cac3b8171530fe97fcf09b31e1e2029c6e32300ee1facb9c7de497beb8a99edb -OpenBLAS.v0.3.17+2.armv6l-linux-gnueabihf-libgfortran3.tar.gz/md5/eb8996220a8d2ab0ff3fccf791c19d2d -OpenBLAS.v0.3.17+2.armv6l-linux-gnueabihf-libgfortran3.tar.gz/sha512/f2a91bb7523ed50607936774c6d31bba81584046e0bfffb2cccb84ac3319fd1700003991edf54d1c0af4b0558637275309d826fac76a908e46f5f58f006baba9 -OpenBLAS.v0.3.17+2.armv6l-linux-gnueabihf-libgfortran4.tar.gz/md5/02b7b39750d7f4dd4b37c0260dd5ecea -OpenBLAS.v0.3.17+2.armv6l-linux-gnueabihf-libgfortran4.tar.gz/sha512/1017388c9141381e37625ade63ad58ee16c0da6ec775e0c8f20e13912e155e9e868024595accc388708c22341e36b5b9cd8f9343c904ea8e7d30ec1bf6c05310 -OpenBLAS.v0.3.17+2.armv6l-linux-gnueabihf-libgfortran5.tar.gz/md5/56cc6e5f74809a81319ed36ca783bb81 -OpenBLAS.v0.3.17+2.armv6l-linux-gnueabihf-libgfortran5.tar.gz/sha512/fc416c3842ffd49a1a201138559f4271d92d6840847b8b224046c6a6310f30044c598aee453ac4f5ea52e5aafe1b3ebe1dd55486883d5197f15bc4dfe0262af6 -OpenBLAS.v0.3.17+2.armv6l-linux-musleabihf-libgfortran3.tar.gz/md5/78d82e6b98ce18f3a0ea92f2e18eb1bb -OpenBLAS.v0.3.17+2.armv6l-linux-musleabihf-libgfortran3.tar.gz/sha512/bc7476532fed7efa0726937cc6ae8e4a693929cff2dc49fe28dc16ad4d3b18265b907ec0c14e12822d00a018d49dfa487fc3d7867da5c428ced381ccfdf346c0 -OpenBLAS.v0.3.17+2.armv6l-linux-musleabihf-libgfortran4.tar.gz/md5/e55e149728e4e2c18957f6db4dc38c4f -OpenBLAS.v0.3.17+2.armv6l-linux-musleabihf-libgfortran4.tar.gz/sha512/e0403a40a91b2f7db4b23ba46b221b39996f7e6c8a417a4b0346c728e1e8520651e0a3a9ef6bcc0214251f34a968a42bfc124ddf4ea6b4fa2d1122a1e7540365 -OpenBLAS.v0.3.17+2.armv6l-linux-musleabihf-libgfortran5.tar.gz/md5/71f7071a2702ccb32cb9eb296c921210 -OpenBLAS.v0.3.17+2.armv6l-linux-musleabihf-libgfortran5.tar.gz/sha512/29861c10bc8fbdb9163c21e133ac972898ce01eadfc38af089cab680d1d059cbd40ed16304ea3b256844c68070233dfce4197d690080cc9ec12961b8d56b5a94 -OpenBLAS.v0.3.17+2.armv7l-linux-gnueabihf-libgfortran3.tar.gz/md5/b6c52ebccedf4d31ad03e4e883c9cb85 -OpenBLAS.v0.3.17+2.armv7l-linux-gnueabihf-libgfortran3.tar.gz/sha512/f9c04600842629b4ad4dea8afcfa54bc2e06bc4f204714d725e1e87044b155261870ec74bebd05ed21739c6e81e2876226732cf65367e12cb3e52c4fac1db332 -OpenBLAS.v0.3.17+2.armv7l-linux-gnueabihf-libgfortran4.tar.gz/md5/3c154804cea0f5b83a5bb278d8a2bac0 -OpenBLAS.v0.3.17+2.armv7l-linux-gnueabihf-libgfortran4.tar.gz/sha512/5ccf2cab5a473619cfca7f381aa4c5da1f2057d10235224aad76d40c9349880d4e0f84dfe173f1f47653c82ff523fffd01bb6360179d2b1e4687029f64fc2d81 -OpenBLAS.v0.3.17+2.armv7l-linux-gnueabihf-libgfortran5.tar.gz/md5/f5cecf92901773f2aebb13cf23e9603b -OpenBLAS.v0.3.17+2.armv7l-linux-gnueabihf-libgfortran5.tar.gz/sha512/855763d0071009c4d799942e86808c90e06c00a78db4350f8b798a414fad333e5b3fca7397cfcdfc06c5718497d1f19a4c19bc79f8d23685d064947585e98a4f -OpenBLAS.v0.3.17+2.armv7l-linux-musleabihf-libgfortran3.tar.gz/md5/16376d821f9b6b16d7b0ee1890ae79af -OpenBLAS.v0.3.17+2.armv7l-linux-musleabihf-libgfortran3.tar.gz/sha512/68319193bfc960d7879cf2370fe17415d15086587958dfc85bb781c26332399b75cf3928ac0e6d727f6d54ecb41425f1bd724eba4bdba2648c73cc860ff7eba6 -OpenBLAS.v0.3.17+2.armv7l-linux-musleabihf-libgfortran4.tar.gz/md5/7d8099352db1e40a02bf80172979b2f3 -OpenBLAS.v0.3.17+2.armv7l-linux-musleabihf-libgfortran4.tar.gz/sha512/5e73b0b13fe6db964332d663475590d750c3a21c85dd9d2bf181acc7834d22ae94eca7cd69f0dfe58fc4b195dfcdb28bdf526d3603e5706350153a71223f377e -OpenBLAS.v0.3.17+2.armv7l-linux-musleabihf-libgfortran5.tar.gz/md5/efd2b34c3931fe3354ab49f8d6fb330c -OpenBLAS.v0.3.17+2.armv7l-linux-musleabihf-libgfortran5.tar.gz/sha512/ce5f743e261e2801beb075b48d87ff756c8fe157042beb2ffc3d7b506cdf182da11d07bd24dd543103d549f20b83212a0d390eb36c3d9ad715d9ca2cabdeca50 -OpenBLAS.v0.3.17+2.i686-linux-gnu-libgfortran3.tar.gz/md5/f52216036e4f1be71257bc876c67d95b -OpenBLAS.v0.3.17+2.i686-linux-gnu-libgfortran3.tar.gz/sha512/f83db9977940844b220a1ba0e2c2f3c63dfd355301e5d14b01ad85599fb931f5b797bc2ace5563ee5df47a243cac1800514cbe4884ca2a33db78cb1f9937185d -OpenBLAS.v0.3.17+2.i686-linux-gnu-libgfortran4.tar.gz/md5/381088794504a68c826d62cc27d14b9c -OpenBLAS.v0.3.17+2.i686-linux-gnu-libgfortran4.tar.gz/sha512/60b8fa109d32764ad9306e386aabb1ee6809aa03e04253a23a6ea97626d520bafa2ae09ea2f6762fa6bc9d88295bf7dd59fd2978e510c3c63925e7a6560947c2 -OpenBLAS.v0.3.17+2.i686-linux-gnu-libgfortran5.tar.gz/md5/f560fcacad77bf87d8d5945c921938e2 -OpenBLAS.v0.3.17+2.i686-linux-gnu-libgfortran5.tar.gz/sha512/9741eea135584ca23b74827ae02c8f2a91dc8a54b83401e0b2e119aca8c48736ba9816fc224a57f853cfe18fd10467b7f9934f3a10a50073af333270622b4796 -OpenBLAS.v0.3.17+2.i686-linux-musl-libgfortran3.tar.gz/md5/2c52064ddbd658e158347b62ffaa1cb2 -OpenBLAS.v0.3.17+2.i686-linux-musl-libgfortran3.tar.gz/sha512/4fba023c3caefe5fdddf27bac7915d075073c6ed0589348c26864686680710b7e84518072c8e94bdf444e25b5063ee6655afefcb1bf72e64ee5e3247e16fb39a -OpenBLAS.v0.3.17+2.i686-linux-musl-libgfortran4.tar.gz/md5/66da3df20820d2ee0de93e8a512aa5dc -OpenBLAS.v0.3.17+2.i686-linux-musl-libgfortran4.tar.gz/sha512/dca0075ba332ce1e68543f77b4ef666265d8e0bb443171d8cd53775800a3b8e13a755a9de067bcf4503835949bd1bc123f241a32fb74ec0014ef642151f36f1c -OpenBLAS.v0.3.17+2.i686-linux-musl-libgfortran5.tar.gz/md5/2df728b678feae582515a048abc6a3d0 -OpenBLAS.v0.3.17+2.i686-linux-musl-libgfortran5.tar.gz/sha512/755480899352f501fd2bc98adf5cd38a0869b7afbb8d3eb4de173d51ab355f31f03937d6fc2a8f560ca840f3adc04084090a11e495b00b04b465ffb1e0d003e5 -OpenBLAS.v0.3.17+2.i686-w64-mingw32-libgfortran3.tar.gz/md5/52b682596ac8a728bef3baa4e3bcc156 -OpenBLAS.v0.3.17+2.i686-w64-mingw32-libgfortran3.tar.gz/sha512/a6b59fef2d03da5a6246bf1832f0dfa654ab99d0275f69f280bdc54d9a8ab19d2ecce4f53d0f2406114ebdac43b09131c7c3982311f627810cd1de3001bd06b9 -OpenBLAS.v0.3.17+2.i686-w64-mingw32-libgfortran4.tar.gz/md5/0b63ad0bbada8158a000b2f1f64579df -OpenBLAS.v0.3.17+2.i686-w64-mingw32-libgfortran4.tar.gz/sha512/ace0c217299296662ed2e2a479096f26e0bf3a14166429b089ca856214c3d46442ad1b71ae94e2b14fe654fc5acdd940e3ad3970f956e75377601fd99f82b270 -OpenBLAS.v0.3.17+2.i686-w64-mingw32-libgfortran5.tar.gz/md5/a03556c3a4ee2d02f956aa011e5a53ad -OpenBLAS.v0.3.17+2.i686-w64-mingw32-libgfortran5.tar.gz/sha512/dde7ea92fdd47ec05edbeeb71fd3d75cb8b5ba5893e18419e47fd1f06032177a9453fc5920c6bd08aec4e2381c5f2c606ce9df7cbbecdda67d2e67aec8be3265 -OpenBLAS.v0.3.17+2.powerpc64le-linux-gnu-libgfortran3.tar.gz/md5/8c8b0dbb3e0c81d9430460c421dd76ab -OpenBLAS.v0.3.17+2.powerpc64le-linux-gnu-libgfortran3.tar.gz/sha512/8639a186f74c9bf4bf5f9e2f69becf700a3ebec4e119519bdbad53fef559fd525e5f532bf7ea5a63bd29059d9c0564eec89a1cf7802cc7f6a3aeb4be9af3cbec -OpenBLAS.v0.3.17+2.powerpc64le-linux-gnu-libgfortran4.tar.gz/md5/e67d9c5a54b6a5dda63e0fe5ef5b24ad -OpenBLAS.v0.3.17+2.powerpc64le-linux-gnu-libgfortran4.tar.gz/sha512/960cd0bf59fed7c70115358a673cc049cb539aa1b015cb473697309327e3b9afb9447b62239d58d8c56a9e8b1955b2b097b31c14b0013cafe77fbb4b967679be -OpenBLAS.v0.3.17+2.powerpc64le-linux-gnu-libgfortran5.tar.gz/md5/028c1ed0a8b84c83ec64b2970b1739fc -OpenBLAS.v0.3.17+2.powerpc64le-linux-gnu-libgfortran5.tar.gz/sha512/2427b8f4de817ffbbd697f8b7caf710c3a3d9c02045a9650e8fde26c891c7cdc70482bda14f067b0cfa29d436a53f4484a00da8caba6188cba9fe25e7b57dc4c -OpenBLAS.v0.3.17+2.x86_64-apple-darwin-libgfortran3.tar.gz/md5/0277b078caf9b0f0a33bf1da351fcac0 -OpenBLAS.v0.3.17+2.x86_64-apple-darwin-libgfortran3.tar.gz/sha512/52c11d822859209f989462aa38cb8c3a7886cd881da40699a06998498d59bfe40276196218c122b8c0c314384a27e7e4b1b6181c818ad1e543cd2af896be521c -OpenBLAS.v0.3.17+2.x86_64-apple-darwin-libgfortran4.tar.gz/md5/d43dd98167a2c99bd4bbd3f52271595b -OpenBLAS.v0.3.17+2.x86_64-apple-darwin-libgfortran4.tar.gz/sha512/5eef221ed4e30090feec8dfa32a732a1987c692dbd2cf943aafb733ad4e5bd669ec55919ca5c89562e2500b4b1fbaffd6b1bbc8de3f71c9dc0037104412bb234 -OpenBLAS.v0.3.17+2.x86_64-apple-darwin-libgfortran5.tar.gz/md5/e93a6128adb949c43ea946ceca159d38 -OpenBLAS.v0.3.17+2.x86_64-apple-darwin-libgfortran5.tar.gz/sha512/3fa4829b0c18085e935b1c3b7b5062a06ab4ebff60948ae6196ada22476798ee68b4e7b637cf3e5df9dc4dc8a5dbf7c924960b89d58de5c45dc8c8ca4834532a -OpenBLAS.v0.3.17+2.x86_64-linux-gnu-libgfortran3.tar.gz/md5/eddb496fe2c7915d61a4ead82c2622ff -OpenBLAS.v0.3.17+2.x86_64-linux-gnu-libgfortran3.tar.gz/sha512/071d471c973bab1986fe32cd76f4f93eba49fbdf0f72561b90d09b846ce8990e20f328ef1ddfa5e0aa1483f4d95ede80d66fde197bdfec47ea9642a2f16b85d0 -OpenBLAS.v0.3.17+2.x86_64-linux-gnu-libgfortran4.tar.gz/md5/91050bb45fc71c6532d9b3a204903cab -OpenBLAS.v0.3.17+2.x86_64-linux-gnu-libgfortran4.tar.gz/sha512/b02a226dab088e289b4bdcbf6f3ad2319ba26fa880ade277383b482c1e65bc056b834056d7eec0c75b425615d4167bfca581252eb31b87bd2b53d597fb8a47f0 -OpenBLAS.v0.3.17+2.x86_64-linux-gnu-libgfortran5.tar.gz/md5/87a0516c856af6128e2ecd2631c19d34 -OpenBLAS.v0.3.17+2.x86_64-linux-gnu-libgfortran5.tar.gz/sha512/73012b9e99c57fc812e0f64fda6233ce204f2cdfc255ebbea221f614fd1d7ccdf5b2e1f017f55864a5dae8febbd1ed2fafb1fb3a79a53b8c1f1c7d6455ab7fed -OpenBLAS.v0.3.17+2.x86_64-linux-musl-libgfortran3.tar.gz/md5/6446a0328a83c504740b81e0a93087c5 -OpenBLAS.v0.3.17+2.x86_64-linux-musl-libgfortran3.tar.gz/sha512/8f77e02f32e69bf24205f10a3524d96d8bf79050d73f51a522db4228744ad9745a02c1bae1fdd3236a195481b93bec06e92a266fcdc36ea1bcedde33362c51d5 -OpenBLAS.v0.3.17+2.x86_64-linux-musl-libgfortran4.tar.gz/md5/6de9e28283dc703e8597cfe81cb036be -OpenBLAS.v0.3.17+2.x86_64-linux-musl-libgfortran4.tar.gz/sha512/9d99cc42bf17ef982c4884774a43beeb2a160db950a31a5b1970dcdac38ffad316bc21830878aae818cfb4235fe486d757c5d67816ffd556b161acbe66c686fd -OpenBLAS.v0.3.17+2.x86_64-linux-musl-libgfortran5.tar.gz/md5/f1ebb2a6447a2a44c52dafe94499b2f3 -OpenBLAS.v0.3.17+2.x86_64-linux-musl-libgfortran5.tar.gz/sha512/9d1b57a4fff907e7f730de7090e285c5158bcda0867730c23e32cfde4e1b4e5d9be27d19df26178d35fc6f578290e43e120ddcd76854df3c9155b6144ab85dcc -OpenBLAS.v0.3.17+2.x86_64-unknown-freebsd-libgfortran3.tar.gz/md5/e12409bcb87b4889aef1ee6055193777 -OpenBLAS.v0.3.17+2.x86_64-unknown-freebsd-libgfortran3.tar.gz/sha512/f93f703bc74ab355b7fd09f057d7cc0de0bc3a21193e7515bdc4601612ae8d2cfdb4afa61c9450db28058c0cf311e93a2c12a0f921633003df7fca0f4a2e47c4 -OpenBLAS.v0.3.17+2.x86_64-unknown-freebsd-libgfortran4.tar.gz/md5/80e9374a5c694c62085099d16e12b0c5 -OpenBLAS.v0.3.17+2.x86_64-unknown-freebsd-libgfortran4.tar.gz/sha512/cb235f5415fbf7b96c5013e9931b5790e15262f2bb65512064af31e1ec31af86f9a64f4b9874ec97c861ed001ebd0602bff860dda0703bf174db80332e77dd02 -OpenBLAS.v0.3.17+2.x86_64-unknown-freebsd-libgfortran5.tar.gz/md5/42a455ed7d2f102617f7344684c6b532 -OpenBLAS.v0.3.17+2.x86_64-unknown-freebsd-libgfortran5.tar.gz/sha512/8e254f1eca11673c859255f257f2015a1fa285554c0697f4602e64770dfa6f7738149d4aadb5f6451cfa2a21c963f61233535ca98af9f0e1b71137eedef99c22 -OpenBLAS.v0.3.17+2.x86_64-w64-mingw32-libgfortran3.tar.gz/md5/d648f4a82c849bb7d6d6a5290868403c -OpenBLAS.v0.3.17+2.x86_64-w64-mingw32-libgfortran3.tar.gz/sha512/a80c9d4af3f4bff2803a1adf1439e1894197a4a86660e5c4bb25741be590e81785711022928910267c862c4368e5aea2f645bb159e23c403135019c6be31780b -OpenBLAS.v0.3.17+2.x86_64-w64-mingw32-libgfortran4.tar.gz/md5/3e1be20b44219134e47e816682b0b8eb -OpenBLAS.v0.3.17+2.x86_64-w64-mingw32-libgfortran4.tar.gz/sha512/03c64778515e007574c9d14b2dc3dc53dddbb01f6af4872858f5006da446be2ed91b0e07d119651d40d8018968cdf2d3fcc8eebd4834d07b25c2201bb6c3183a -OpenBLAS.v0.3.17+2.x86_64-w64-mingw32-libgfortran5.tar.gz/md5/bc04ffe4100d89fc5eced47d1ac894c4 -OpenBLAS.v0.3.17+2.x86_64-w64-mingw32-libgfortran5.tar.gz/sha512/ab8aea7d065a560305821d199d216e3dfe556e3ec1ebfc98507914fab355e2a0231f628fc7fe4c48dffd80d5d4c4a5a90fd540c8ba90236702ef660af635c09e -openblas-d909f9f3d4fc4ccff36d69f178558df154ba1002.tar.gz/md5/4acd59865ca8b50c823bef1354148930 -openblas-d909f9f3d4fc4ccff36d69f178558df154ba1002.tar.gz/sha512/227ee7decccf9bdd2e5754757f590e32ada95b576db9eddc2c74ef06d35aba1db9438acaf57750184baacac741917f7f5ad9f15991d31314480db371fe59cc17 +OpenBLAS.v0.3.20+0.aarch64-apple-darwin-libgfortran5.tar.gz/md5/036acd7c7b68432f01f2a980bc4958be +OpenBLAS.v0.3.20+0.aarch64-apple-darwin-libgfortran5.tar.gz/sha512/db2c995b09b5ab046491257b44a8806fd5e254bbf4b4df6e9281ffc8d199745a3d6fea912da2fdd657447e194c73db52cf7acb348b49fd37758b6fbbbdfd3a93 +OpenBLAS.v0.3.20+0.aarch64-linux-gnu-libgfortran3.tar.gz/md5/7c5de800082f39fea05d1fdf9cdf2e79 +OpenBLAS.v0.3.20+0.aarch64-linux-gnu-libgfortran3.tar.gz/sha512/78775b01c1f24848da6111d9f4746f0b44f5966aa202af00182c4da649e4b4cf630cd1bb90e8ed32f54dfdbee0f6d03b87c171f03fee9b37886634a20546d627 +OpenBLAS.v0.3.20+0.aarch64-linux-gnu-libgfortran4.tar.gz/md5/eefc198718aa837a04e0f8e6dbdc8b0f +OpenBLAS.v0.3.20+0.aarch64-linux-gnu-libgfortran4.tar.gz/sha512/cdc351d992b795732e02698df8f5f31c301dbcd6d995d2a35790461b08f3c942d70e8f7c031a943873eead4fcbd1e73649aafdfdb7450b955f4848be2e9a43de +OpenBLAS.v0.3.20+0.aarch64-linux-gnu-libgfortran5.tar.gz/md5/8d9ced4a8e441713ceb0d79b72b43ca5 +OpenBLAS.v0.3.20+0.aarch64-linux-gnu-libgfortran5.tar.gz/sha512/b1dfc3f4a539d01266e3e5d400864cd445c4bc561de464e2f6c9eb5704541aa436944f6bfc89be1948e9675f1a83098d77fe52f70886dc90d54206c81f350277 +OpenBLAS.v0.3.20+0.aarch64-linux-musl-libgfortran3.tar.gz/md5/fa63d8009ac2605208ceea9f6183acdd +OpenBLAS.v0.3.20+0.aarch64-linux-musl-libgfortran3.tar.gz/sha512/92b8e2fd2bc45c60aaf8d79c59f96b721d969cd3320c0b04989a5a48099cae213fd4a6aa9dca45910d881e495d87863513b23ee7c433c894655cf72c7b009323 +OpenBLAS.v0.3.20+0.aarch64-linux-musl-libgfortran4.tar.gz/md5/68672f9cbcd9bee92c89b19599897034 +OpenBLAS.v0.3.20+0.aarch64-linux-musl-libgfortran4.tar.gz/sha512/4c19f3cb7afb52cd54c3852fef3815a23e57b5c2ebd9b647ad43ee62191b74474c787b22d6213555f38b8233b96d479631881d522c7bdd544954a9f04b51c509 +OpenBLAS.v0.3.20+0.aarch64-linux-musl-libgfortran5.tar.gz/md5/7fd9458e1482d46f761d6a519999a648 +OpenBLAS.v0.3.20+0.aarch64-linux-musl-libgfortran5.tar.gz/sha512/2e20c845deb5c87c6e02a3512728a27204193a764f8ead1a66ce053b66d03bb853bbf40289727b1b635b17423416a7a69c633242c12f98d3ec1eae5e82a88613 +OpenBLAS.v0.3.20+0.armv6l-linux-gnueabihf-libgfortran3.tar.gz/md5/0868668b73c84e14edb634482d59eddc +OpenBLAS.v0.3.20+0.armv6l-linux-gnueabihf-libgfortran3.tar.gz/sha512/c87f91120db8d3b32cc12077b1e36110f89253fde22aae9de88945fc731ee74271acf31cabac9971635725f586b65cf6b1b9badebcbba5408b0ff4c68b580ccf +OpenBLAS.v0.3.20+0.armv6l-linux-gnueabihf-libgfortran4.tar.gz/md5/9e84b7585acf2bb71781002b2238d888 +OpenBLAS.v0.3.20+0.armv6l-linux-gnueabihf-libgfortran4.tar.gz/sha512/14b57f9d5691997cf01bc6187a1a1d58d07d162ab8eb2a480e7c42f0cff1583161c8b1a059c9eeb83e7ed276c8ffe2e193db001a3b51724e5af24c72f5e33572 +OpenBLAS.v0.3.20+0.armv6l-linux-gnueabihf-libgfortran5.tar.gz/md5/a4768ea555e68fc755da169f1c7eb21c +OpenBLAS.v0.3.20+0.armv6l-linux-gnueabihf-libgfortran5.tar.gz/sha512/490ce2b60cda0b5ed40df103e79b83ab75dd03779ea88b0ae5d3b76acadcf4810b35f69566e396b438d881130e43fd0dbff1672d0383dc7fe275f44574d8830b +OpenBLAS.v0.3.20+0.armv6l-linux-musleabihf-libgfortran3.tar.gz/md5/1a4e7e7cfdefcd878c18bab39b9c80cc +OpenBLAS.v0.3.20+0.armv6l-linux-musleabihf-libgfortran3.tar.gz/sha512/15b512728b49782717770f044958ed3afcd54d6cc70b362a7c96dbadf7599bdcdd157ee021287a70e45957d0a856417540e64e2399cc392b9de55036d607fa29 +OpenBLAS.v0.3.20+0.armv6l-linux-musleabihf-libgfortran4.tar.gz/md5/63ce4aa67d1d56f2cf456285546d3eeb +OpenBLAS.v0.3.20+0.armv6l-linux-musleabihf-libgfortran4.tar.gz/sha512/ac0bd761ef574d3533fa7f6110b9ecf992edf7a68c20fff4faf4b7372d3de4c5ed558119dcdb669296aab5c0da5ce0f51f54abfe998958e1924cfa0eb958305e +OpenBLAS.v0.3.20+0.armv6l-linux-musleabihf-libgfortran5.tar.gz/md5/581bcbd14328d82258511f8b91d8bf84 +OpenBLAS.v0.3.20+0.armv6l-linux-musleabihf-libgfortran5.tar.gz/sha512/be66567c762f70885b187dc8912f83003c69dd5000387b5b82162ba9f47acb17d855f8f5bda2f31d3fc7e01d2aae3cd6b2392632d70ec34f2d648010a8b11f38 +OpenBLAS.v0.3.20+0.armv7l-linux-gnueabihf-libgfortran3.tar.gz/md5/30dfd96f7f3d35df95e70d506f35c9f2 +OpenBLAS.v0.3.20+0.armv7l-linux-gnueabihf-libgfortran3.tar.gz/sha512/84213bbff84899882ab43599f3aeab1c6e3ee8f7158a3873ec2d6a3166e69036c16d742d25c476468f64b6644a2f798485e50427139880f1ae933ad507a2952c +OpenBLAS.v0.3.20+0.armv7l-linux-gnueabihf-libgfortran4.tar.gz/md5/4b82a4e68a43d29538a318763004aa94 +OpenBLAS.v0.3.20+0.armv7l-linux-gnueabihf-libgfortran4.tar.gz/sha512/94d35902c34e6fa68a0648cab65db49650c73ed21d69ee667350cbbb81028413b92fc30e16504648a6b42039f483d327264a3ff39d546cd30241f4672f9300a2 +OpenBLAS.v0.3.20+0.armv7l-linux-gnueabihf-libgfortran5.tar.gz/md5/7e290717c23a468383bd66b46eb58fac +OpenBLAS.v0.3.20+0.armv7l-linux-gnueabihf-libgfortran5.tar.gz/sha512/432cf42a320a265b9259d743eaca75b884663877858149b0feb83948436a941940955c0c89c6de9ca114f0bbf153127a046813195f4669a81cab1ce244cc5a6b +OpenBLAS.v0.3.20+0.armv7l-linux-musleabihf-libgfortran3.tar.gz/md5/f72bf36862607c57fc9cee5dc3f94dac +OpenBLAS.v0.3.20+0.armv7l-linux-musleabihf-libgfortran3.tar.gz/sha512/caecc044e25d2939eec45924d69e64d3854fc54626a56126454fb3855ae2dabf36fc248d7ef9d240f15e8883787a43539e2a0d8dc68fc5c93a094ded94f3b976 +OpenBLAS.v0.3.20+0.armv7l-linux-musleabihf-libgfortran4.tar.gz/md5/66bfd606fc80e02999ad44243d3b686a +OpenBLAS.v0.3.20+0.armv7l-linux-musleabihf-libgfortran4.tar.gz/sha512/b3d76ccf40af1de018e829f5dd696c6d18ad1fd96657a06d190a9d4e939cad5062a3a2ffaeca2ce7f75e822694ae0b817568dd8f115e089a59590bb34af264f8 +OpenBLAS.v0.3.20+0.armv7l-linux-musleabihf-libgfortran5.tar.gz/md5/ef7aca842a623246b4e2876ff28c53ef +OpenBLAS.v0.3.20+0.armv7l-linux-musleabihf-libgfortran5.tar.gz/sha512/a59feb34806d651a2a3614bcc5203407db626e96dabeb6bb12b8d73915cfd87dc02b0e54704c5d0f1b8ab984d85ee64509a934884640d2522fc4a9835989aed8 +OpenBLAS.v0.3.20+0.i686-linux-gnu-libgfortran3.tar.gz/md5/f2ba9ed0f68447aeddfcf3ac883cf83b +OpenBLAS.v0.3.20+0.i686-linux-gnu-libgfortran3.tar.gz/sha512/1b6f300febf5ceeb0045c46cc3d6e9f2481cba2ceb97dcafff1667f06b8b96a2ad4975853e6bc2e3e6715ade28be5fb569fdae005f4fca2140a5557d4a0845ca +OpenBLAS.v0.3.20+0.i686-linux-gnu-libgfortran4.tar.gz/md5/b39347f487b46996de98d9a453ae804e +OpenBLAS.v0.3.20+0.i686-linux-gnu-libgfortran4.tar.gz/sha512/a923a92467b4582f69ec9d96556c8f2ef55a3f99dacecf0491da9740912d14d09a9ba86bdb5fcfbaab87250c57a0c077c2f6ccc08bf3236ba5c7d98822e9c32a +OpenBLAS.v0.3.20+0.i686-linux-gnu-libgfortran5.tar.gz/md5/6d9b4adf3fa54151c45b832b5869409e +OpenBLAS.v0.3.20+0.i686-linux-gnu-libgfortran5.tar.gz/sha512/f15583c15fb4e4b6a38353fbbce2aa57c8f46d58e6c5464a685e5fb0afd76f1bf9b3986c1d34af643a8c9b3a8a24ef63389982c2e8ffbf91a63e8f1ccca2cce5 +OpenBLAS.v0.3.20+0.i686-linux-musl-libgfortran3.tar.gz/md5/fa46f28f624e8c0752bb76abc04a41d5 +OpenBLAS.v0.3.20+0.i686-linux-musl-libgfortran3.tar.gz/sha512/76018ed804f25212760f1128f7d3823a1c8ba72b8cf5d83aa5be5c5f6e3de8076b04be9d5b659af75e3c2fd5cb9a0654dba59651f010534faf174a6c7d836cd3 +OpenBLAS.v0.3.20+0.i686-linux-musl-libgfortran4.tar.gz/md5/48411109935a2ada9d2e336515f36b6f +OpenBLAS.v0.3.20+0.i686-linux-musl-libgfortran4.tar.gz/sha512/9be06c11fb248d6da47dab21f60d1eec6b486a137048f79f2138b5fe6818846ac198da7d73ab93ec161e8861d7e670b587b6eeb846c571497e96023934127903 +OpenBLAS.v0.3.20+0.i686-linux-musl-libgfortran5.tar.gz/md5/b0a81e44dd4a216c60b6ff139512d7b5 +OpenBLAS.v0.3.20+0.i686-linux-musl-libgfortran5.tar.gz/sha512/1b1c3cc5e62af6af8e106c60c59d7ff685d567e93dce19643ba8c0547200000bae96a3473573619ab235c34ff8e65745266001cdc868e948ff3ecaa9ba93389f +OpenBLAS.v0.3.20+0.i686-w64-mingw32-libgfortran3.tar.gz/md5/18988c19ea5bdb81d97f8ce4456319f6 +OpenBLAS.v0.3.20+0.i686-w64-mingw32-libgfortran3.tar.gz/sha512/466d6b05dcf00b6f09c1a8b8fda97a0035838d73d77954f6cd499358e8160af6cf3e8aac97d0f7ba7ced144db1362a9ba126fb113a4469c232a6b9706dc3dc32 +OpenBLAS.v0.3.20+0.i686-w64-mingw32-libgfortran4.tar.gz/md5/d0aa399c07712e9a520a6cb8067bda63 +OpenBLAS.v0.3.20+0.i686-w64-mingw32-libgfortran4.tar.gz/sha512/7c3e0b1c18812719be4d86a641d25d927c9c8cbc6e1571c7a46ca27672ada00cbe3879faf0b5aeaaa0454907551953a20a56be0bc24b651df117532ace2f9067 +OpenBLAS.v0.3.20+0.i686-w64-mingw32-libgfortran5.tar.gz/md5/90d51a2f41c11fc8d1896597dd106cd6 +OpenBLAS.v0.3.20+0.i686-w64-mingw32-libgfortran5.tar.gz/sha512/683c40193ec7a4612c4a36e9d9f6d9443bfb72dbfed7fa10b200305c94589fd75362670d9b4d7646f24b4f7933cfc55a2496030907e2d3fd30b0eed8b6a2d10b +OpenBLAS.v0.3.20+0.powerpc64le-linux-gnu-libgfortran3.tar.gz/md5/30d5022d6f52adccfaf6b3dd837b6151 +OpenBLAS.v0.3.20+0.powerpc64le-linux-gnu-libgfortran3.tar.gz/sha512/433a520458d6804eccf69c74fe357e6d819223b0398007f17420a6aa77a466177d9dcd4f467821b4d99f4397f5e0c1dc0864512a7f69c43f23bc40b6414449b6 +OpenBLAS.v0.3.20+0.powerpc64le-linux-gnu-libgfortran4.tar.gz/md5/2848232be1646333d6d413a588519d99 +OpenBLAS.v0.3.20+0.powerpc64le-linux-gnu-libgfortran4.tar.gz/sha512/edb51d55f602d2a271109dbc12e59e23c232e58833bcc34dd857858d10d318eac99ba300fe4c6480b995e152ff036ff175218a2f4b29910a27f1861543d1e978 +OpenBLAS.v0.3.20+0.powerpc64le-linux-gnu-libgfortran5.tar.gz/md5/8bd4f4d571dc382eaf0084000596276e +OpenBLAS.v0.3.20+0.powerpc64le-linux-gnu-libgfortran5.tar.gz/sha512/f9507f6dc53c632e0f26de074bcd312956b2fb492e9f1d32e3cdf1a6099d6f2b17eea09ae825b2414a28dfbd6958813cffa289fde0a15cf7cba4e6b3653d2a28 +OpenBLAS.v0.3.20+0.x86_64-apple-darwin-libgfortran3.tar.gz/md5/c644f00642c69946d12b8f1f96a8e766 +OpenBLAS.v0.3.20+0.x86_64-apple-darwin-libgfortran3.tar.gz/sha512/2bd51e9adda3e0955ab26c5c178e9a75a8d9c1b4cd2fd221bbb7b9eb72337cd5034f42b53aaddcf97a807e01f2b9836f9be95a5c6517c831374a3b5148b6e380 +OpenBLAS.v0.3.20+0.x86_64-apple-darwin-libgfortran4.tar.gz/md5/cea0d5ad3528298e4512c900a13f21ec +OpenBLAS.v0.3.20+0.x86_64-apple-darwin-libgfortran4.tar.gz/sha512/379ad13b723acde1d2239335c2611a9ebd2abe1432931d4c2395fce9f50bbd5d830a23fd5ea5afc1fc251704e4ed880468abde42bb0ea75b6bb0abb9a7753c5b +OpenBLAS.v0.3.20+0.x86_64-apple-darwin-libgfortran5.tar.gz/md5/bc726288a19a8bdcef3205de12b5f172 +OpenBLAS.v0.3.20+0.x86_64-apple-darwin-libgfortran5.tar.gz/sha512/3e26b8a2075f997ded8750d84e3257b895e7e05adac77d836e66fa7478b43368b7d4b7a458c6991cb642ce0d135b1b507dade7302c4f5a44aabe637849bc1acb +OpenBLAS.v0.3.20+0.x86_64-linux-gnu-libgfortran3.tar.gz/md5/d162add49c7ee74dfc23b820bbd363b6 +OpenBLAS.v0.3.20+0.x86_64-linux-gnu-libgfortran3.tar.gz/sha512/70bcc15f37e4cd822c2f95d8fd23e912829450825399d31c29c00a4ea219ca37f8831d3132ae4b5972fe9ec95c304bd1274a12ec8a8b289b1830cfb7ca0392d7 +OpenBLAS.v0.3.20+0.x86_64-linux-gnu-libgfortran4.tar.gz/md5/f036c51e0954b8b76e3023280144b5ff +OpenBLAS.v0.3.20+0.x86_64-linux-gnu-libgfortran4.tar.gz/sha512/2101747ec254f51fe5c2cfc49ce9599aeacf0d3e7bcb14c9ccaa59d8b0f7e9dcda98ab3ff38973817b736a33ddf654e17748d8a9c3b40e5352a198278484a2f0 +OpenBLAS.v0.3.20+0.x86_64-linux-gnu-libgfortran5.tar.gz/md5/143d8e7cf2fb615ccab6617bffa4acf7 +OpenBLAS.v0.3.20+0.x86_64-linux-gnu-libgfortran5.tar.gz/sha512/6e72144f83cb329301feedea02581a100d137f3b209af4983500c432b6d23cc7473c85a7b1ba90e24965508e74a191b49cea8820b5899793440c3ce067acbe06 +OpenBLAS.v0.3.20+0.x86_64-linux-musl-libgfortran3.tar.gz/md5/871863002d0053784a81409b4581c8cd +OpenBLAS.v0.3.20+0.x86_64-linux-musl-libgfortran3.tar.gz/sha512/908936494c981e14bcd7818043efe979d9522ae1c9ebcd69feb853c46a2249da1cb5292844d0de7276762a21ad8680a1117229f3ad53332b536233d8722c4d85 +OpenBLAS.v0.3.20+0.x86_64-linux-musl-libgfortran4.tar.gz/md5/ce4897980b12374801095fadfad11196 +OpenBLAS.v0.3.20+0.x86_64-linux-musl-libgfortran4.tar.gz/sha512/ba551942563a58fd22d182a29cee83ce5f51db10e52bc8cb27d979dc71632484e1acb713d4304d773c3111d5dba532bd65651374e91a364f8125295acacfffd4 +OpenBLAS.v0.3.20+0.x86_64-linux-musl-libgfortran5.tar.gz/md5/301ae23724b44c1d10e4febdc6738df3 +OpenBLAS.v0.3.20+0.x86_64-linux-musl-libgfortran5.tar.gz/sha512/2f1479b1f1d10682751b025493bc38cd5eb9854620024b1f0ac45ba0f7a7621b4795c4c2f89eece5c80b671387d095b118d58d8ba201214f45bcea1ac64fca91 +OpenBLAS.v0.3.20+0.x86_64-unknown-freebsd-libgfortran3.tar.gz/md5/51088d57d2a9e9e50259128a0ac48727 +OpenBLAS.v0.3.20+0.x86_64-unknown-freebsd-libgfortran3.tar.gz/sha512/c88b1eb662c16b75c46a25959f6fff22de2cfb2a97ff1c0cd482528e83d54a4d8bbf33c3e7d6a79ad75998d0c6d46ef6f245e8ad406d1a072907138d7ca4a34c +OpenBLAS.v0.3.20+0.x86_64-unknown-freebsd-libgfortran4.tar.gz/md5/06167501fc4cc7b6587ead3696ef72af +OpenBLAS.v0.3.20+0.x86_64-unknown-freebsd-libgfortran4.tar.gz/sha512/a853a4c5163e0bc0266e75df0b208794e8439a008b625b520b51e7891825a355960f62fe2275e4f849c345862fabf0339d0d22d4bdcd87acfb17ffd65627f74d +OpenBLAS.v0.3.20+0.x86_64-unknown-freebsd-libgfortran5.tar.gz/md5/73a43356c9bf374765a2bc8910e2eb49 +OpenBLAS.v0.3.20+0.x86_64-unknown-freebsd-libgfortran5.tar.gz/sha512/0c2092789f4eeab1725cdfd7d308a2ede054b993d6d1a83f671c5c8e9f651565c282af7371c958c61a57679a233d3f62a287afb44225498dc31249f6821ddf98 +OpenBLAS.v0.3.20+0.x86_64-w64-mingw32-libgfortran3.tar.gz/md5/46bd5ef0708671aeb2a533476a04591b +OpenBLAS.v0.3.20+0.x86_64-w64-mingw32-libgfortran3.tar.gz/sha512/1b0a3f9e61101cbf455da70056dea75637f3008df727072a22150072e7bfc773294378fc42a492b2351f9af2d6b7866503c0039f8addeab07d4f4b5d0f42b5fb +OpenBLAS.v0.3.20+0.x86_64-w64-mingw32-libgfortran4.tar.gz/md5/7e412c9961e4762c40cca9c27e5c9aa2 +OpenBLAS.v0.3.20+0.x86_64-w64-mingw32-libgfortran4.tar.gz/sha512/6a275bd153bb0ba227f39ffbfe95ee1f84f42f79361f7d3a7b1a5c29ca253b8d8b2427ce389f10cf2b95fb87d91dcdf1144f24c82d11320a0aad7dfb8d3c0498 +OpenBLAS.v0.3.20+0.x86_64-w64-mingw32-libgfortran5.tar.gz/md5/2a24ea7c7a9bdf8069d7f62c55d09bb5 +OpenBLAS.v0.3.20+0.x86_64-w64-mingw32-libgfortran5.tar.gz/sha512/7f9134df42be432199119b2a5ef5df2552247cca8647546fb755901d5903030fd5cb565c711248f173c71409cd3b30609a2adadf0213c9a096a9b70298b29a87 +openblas-0b678b19dc03f2a999d6e038814c4c50b9640a4e.tar.gz/md5/4586a405791fb16775eb9aecdd7daa59 +openblas-0b678b19dc03f2a999d6e038814c4c50b9640a4e.tar.gz/sha512/c34a498f2f1ecf65c5174a198022558bf6626eb6da0c4191762a35fd9d335c67dd17246cee3ef503301738a202650aaefe5e0073d8abefd3d1b8ba19cc953304 diff --git a/deps/openblas.mk b/deps/openblas.mk index 50873c9220f08..d4ee63a543bf0 100644 --- a/deps/openblas.mk +++ b/deps/openblas.mk @@ -90,12 +90,7 @@ $(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-julia42415-lapack625-openblas3392.patch-applied: $(BUILDDIR)/$(OPENBLAS_SRC_DIR)/openblas-ofast-power.patch-applied - cd $(BUILDDIR)/$(OPENBLAS_SRC_DIR) && \ - patch -p1 -f < $(SRCDIR)/patches/openblas-julia42415-lapack625-openblas3392.patch - echo 1 > $@ - -$(BUILDDIR)/$(OPENBLAS_SRC_DIR)/neoverse-generic-kernels.patch-applied: $(BUILDDIR)/$(OPENBLAS_SRC_DIR)/openblas-julia42415-lapack625-openblas3392.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/neoverse-generic-kernels.patch echo 1 > $@ diff --git a/deps/openblas.version b/deps/openblas.version index 346e75dac614b..ceb01600b0ea7 100644 --- a/deps/openblas.version +++ b/deps/openblas.version @@ -1,2 +1,2 @@ -OPENBLAS_BRANCH=v0.3.17 -OPENBLAS_SHA1=d909f9f3d4fc4ccff36d69f178558df154ba1002 +OPENBLAS_BRANCH=v0.3.20 +OPENBLAS_SHA1=0b678b19dc03f2a999d6e038814c4c50b9640a4e diff --git a/deps/patches/openblas-julia42415-lapack625-openblas3392.patch b/deps/patches/openblas-julia42415-lapack625-openblas3392.patch deleted file mode 100644 index e7b874b961cca..0000000000000 --- a/deps/patches/openblas-julia42415-lapack625-openblas3392.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 2be5ee3cca97a597f2ee2118808a2d5eacea050c Mon Sep 17 00:00:00 2001 -From: Martin Kroeker -Date: Fri, 1 Oct 2021 11:17:21 +0200 -Subject: [PATCH 1/4] Fix out of bounds read in ?llarv (Reference-LAPACK PR - 625) - ---- - lapack-netlib/SRC/clarrv.f | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/lapack-netlib/SRC/clarrv.f b/lapack-netlib/SRC/clarrv.f -index a45f55ac3b..26a9febc87 100644 ---- a/lapack-netlib/SRC/clarrv.f -+++ b/lapack-netlib/SRC/clarrv.f -@@ -351,7 +351,7 @@ SUBROUTINE CLARRV( N, VL, VU, D, L, PIVMIN, - * - * Quick return if possible - * -- IF( N.LE.0 ) THEN -+ IF( (N.LE.0) .OR. (M.LE.0) ) THEN - RETURN - END IF - * - -From fe497efa0510466fd93578aaf9da1ad8ed4edbe7 Mon Sep 17 00:00:00 2001 -From: Martin Kroeker -Date: Fri, 1 Oct 2021 11:18:20 +0200 -Subject: [PATCH 2/4] Fix out of bounds read in ?llarv (Reference-LAPACK PR - 625) - ---- - lapack-netlib/SRC/dlarrv.f | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/lapack-netlib/SRC/dlarrv.f b/lapack-netlib/SRC/dlarrv.f -index 4a59a2bbf9..a1c6e9c9d7 100644 ---- a/lapack-netlib/SRC/dlarrv.f -+++ b/lapack-netlib/SRC/dlarrv.f -@@ -353,7 +353,7 @@ SUBROUTINE DLARRV( N, VL, VU, D, L, PIVMIN, - * - * Quick return if possible - * -- IF( N.LE.0 ) THEN -+ IF( (N.LE.0).OR.(M.LE.0) ) THEN - RETURN - END IF - * - -From ddb0ff5353637bb5f5ad060c9620e334c143e3d7 Mon Sep 17 00:00:00 2001 -From: Martin Kroeker -Date: Fri, 1 Oct 2021 11:19:07 +0200 -Subject: [PATCH 3/4] Fix out of bounds read in ?llarv (Reference-LAPACK PR - 625) - ---- - lapack-netlib/SRC/slarrv.f | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/lapack-netlib/SRC/slarrv.f b/lapack-netlib/SRC/slarrv.f -index 04519fde8c..9448b2fd92 100644 ---- a/lapack-netlib/SRC/slarrv.f -+++ b/lapack-netlib/SRC/slarrv.f -@@ -353,7 +353,7 @@ SUBROUTINE SLARRV( N, VL, VU, D, L, PIVMIN, - * - * Quick return if possible - * -- IF( N.LE.0 ) THEN -+ IF( (N.LE.0).OR.(M.LE.0) ) THEN - RETURN - END IF - * - -From 337b65133df174796794871b3988cd03426e6d41 Mon Sep 17 00:00:00 2001 -From: Martin Kroeker -Date: Fri, 1 Oct 2021 11:19:53 +0200 -Subject: [PATCH 4/4] Fix out of bounds read in ?llarv (Reference-LAPACK PR - 625) - ---- - lapack-netlib/SRC/zlarrv.f | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/lapack-netlib/SRC/zlarrv.f b/lapack-netlib/SRC/zlarrv.f -index 23976dbefe..8d10e3c2e3 100644 ---- a/lapack-netlib/SRC/zlarrv.f -+++ b/lapack-netlib/SRC/zlarrv.f -@@ -351,7 +351,7 @@ SUBROUTINE ZLARRV( N, VL, VU, D, L, PIVMIN, - * - * Quick return if possible - * -- IF( N.LE.0 ) THEN -+ IF( (N.LE.0).OR.(M.LE.0) ) THEN - RETURN - END IF - * diff --git a/deps/patches/openblas-ofast-power.patch b/deps/patches/openblas-ofast-power.patch index c741496cae757..405e3f7581331 100644 --- a/deps/patches/openblas-ofast-power.patch +++ b/deps/patches/openblas-ofast-power.patch @@ -1,17 +1,18 @@ diff --git a/Makefile.power b/Makefile.power -index 946f5523..19593050 100644 +index 28a0bae0..b4869fbd 100644 --- a/Makefile.power +++ b/Makefile.power -@@ -11,14 +11,14 @@ endif - +@@ -11,7 +11,7 @@ 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 ($(F_COMPILER), IBM) + FCOMMON_OPT += -O2 -qrecur -qnosave + else +@@ -22,7 +22,7 @@ endif + ifeq ($(CORE), POWER9) ifneq ($(C_COMPILER), PGI) -CCOMMON_OPT += -Ofast -mvsx -fno-fast-math @@ -19,8 +20,8 @@ index 946f5523..19593050 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) -@@ -51,7 +51,7 @@ endif - +@@ -59,7 +59,7 @@ endif + ifeq ($(CORE), POWER8) ifneq ($(C_COMPILER), PGI) -CCOMMON_OPT += -Ofast -mcpu=power8 -mtune=power8 -mvsx -fno-fast-math diff --git a/stdlib/OpenBLAS_jll/Project.toml b/stdlib/OpenBLAS_jll/Project.toml index 3ab110db99410..21fa9e9f0a0e6 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.17+2" +version = "0.3.20+0" [deps] CompilerSupportLibraries_jll = "e66e0078-7015-5450-92f7-15fbd957f2ae" From e12020f966e70a4db26abd3b00ca4f922ddc16f6 Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Thu, 24 Feb 2022 17:08:37 -0500 Subject: [PATCH 10/46] fix #43411, wrapped `NamedTuple` can be bitstype more often (#44311) (cherry picked from commit f20d5de466def02ec88e2889e80e24e736b0ade4) --- src/jltypes.c | 2 ++ test/core.jl | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/src/jltypes.c b/src/jltypes.c index a24e9f7e488bd..e19b4c536d94d 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -61,6 +61,8 @@ static int layout_uses_free_typevars(jl_value_t *v, jl_typeenv_t *env) jl_datatype_t *dt = (jl_datatype_t*)v; if (dt->layout || dt->isconcretetype || !dt->name->mayinlinealloc) return 0; + if (dt->name == jl_namedtuple_typename) + return layout_uses_free_typevars(jl_tparam0(dt), env) || layout_uses_free_typevars(jl_tparam1(dt), env); jl_svec_t *types = jl_get_fieldtypes(dt); size_t i, l = jl_svec_len(types); for (i = 0; i < l; i++) { diff --git a/test/core.jl b/test/core.jl index 43d6da062560b..6dbd8f3d9fa0e 100644 --- a/test/core.jl +++ b/test/core.jl @@ -7324,6 +7324,12 @@ end @test isbitstype(X41654) @test ('a'=>X41654(),)[1][2] isa X41654 +# issue #43411 +struct A43411{S, T} + x::NamedTuple{S, T} +end +@test isbitstype(A43411{(:a,), Tuple{Int}}) + # Issue #34206/34207 function mre34206(a, n) va = view(a, :) From b4e22094aad654770fe331f8f5b238c69a979e5c Mon Sep 17 00:00:00 2001 From: Elliot Saba Date: Thu, 24 Feb 2022 14:52:14 -0800 Subject: [PATCH 11/46] [macOS] Codesign binary-dist tarballs (#44305) Because we're starting to distribute macOS tarballs as well, let's codesign them by default, when possible. (cherry picked from commit 6b29ebda35b6c844198c5d1533587711a6700df2) --- Makefile | 12 ++++++++++++ contrib/mac/app/Makefile | 3 +++ 2 files changed, 15 insertions(+) diff --git a/Makefile b/Makefile index 086ed515c62b7..952b9a00c1e63 100644 --- a/Makefile +++ b/Makefile @@ -427,9 +427,21 @@ ifeq ($(OS), Linux) endif ifeq ($(OS), WINNT) cd $(BUILDROOT)/julia-$(JULIA_COMMIT)/bin && rm -f llvm* llc.exe lli.exe opt.exe LTO.dll bugpoint.exe macho-dump.exe +endif + # If we're on macOS, and we have a codesigning identity, then codesign the binary-dist tarball! +ifeq ($(OS),Darwin) +ifneq ($(MACOS_CODESIGN_IDENTITY),) + echo "Codesigning with identity $(MACOS_CODESIGN_IDENTITY)"; \ + MACHO_FILES=$$(find "$(BUILDROOT)/julia-$(JULIA_COMMIT)" -type f -perm -0111 | cut -d: -f1); \ + for f in $${MACHO_FILES}; do \ + echo "Codesigning $${f}..."; \ + codesign -s "$(MACOS_CODESIGN_IDENTITY)" --option=runtime --entitlements $(JULIAHOME)/contrib/mac/app/Entitlements.plist -vvv --timestamp --deep --force "$${f}"; \ + done +endif endif cd $(BUILDROOT) && $(TAR) zcvf $(JULIA_BINARYDIST_FILENAME).tar.gz julia-$(JULIA_COMMIT) + exe: # run Inno Setup to compile installer $(call spawn,$(JULIAHOME)/dist-extras/inno/iscc.exe /DAppVersion=$(JULIA_VERSION) /DSourceDir="$(call cygpath_w,$(BUILDROOT)/julia-$(JULIA_COMMIT))" /DRepoDir="$(call cygpath_w,$(JULIAHOME))" /F"$(JULIA_BINARYDIST_FILENAME)" /O"$(call cygpath_w,$(BUILDROOT))" $(INNO_ARGS) $(call cygpath_w,$(JULIAHOME)/contrib/windows/build-installer.iss)) diff --git a/contrib/mac/app/Makefile b/contrib/mac/app/Makefile index edb6f868c9486..81b7e47cdf2cf 100644 --- a/contrib/mac/app/Makefile +++ b/contrib/mac/app/Makefile @@ -50,6 +50,9 @@ dmg/$(APP_NAME): startup.applescript julia.icns make -C $(JULIAHOME) binary-dist tar zxf $(JULIAHOME)/$(JULIA_BINARYDIST_FILENAME).tar.gz -C $@/Contents/Resources/julia --strip-components 1 find $@/Contents/Resources/julia -type f -exec chmod -w {} \; + # Even though the tarball may already be signed, we re-sign here to make it easier to add + # unsigned executables (like the app launcher) and whatnot, without needing to maintain lists + # of what is or is not signed. Codesigning is cheap, so might as well do it early and often. if [ -n "$$MACOS_CODESIGN_IDENTITY" ]; then \ echo "Codesigning with identity $$MACOS_CODESIGN_IDENTITY"; \ MACHO_FILES=$$(find "$@" -type f -perm -0111 | cut -d: -f1); \ From 24e3c06fbda94f01a52fae222a53512db0d46381 Mon Sep 17 00:00:00 2001 From: Yichao Yu Date: Fri, 25 Feb 2022 09:48:24 -0500 Subject: [PATCH 12/46] Make sure all the relocations are filled in for partially cloned target (#44262) We collect the relocations (i.e. the GOT slots that is used in the code) for each target in `tgt.relocs`. Needing a relocation, however, does not imply that the function is cloned for this target within the group (It does mean that at least one target in the group has it cloned). The previous version would miss the relocation in this case. This was triggerred with the following cloning situation caller: clone_1 callee: clone_1, clone_1.clone_3 Since caller.clone_1 may call either callee.clone_1 or callee.clone_1.clone_3 a relocation for callee will be used and is required to be initialized. In addition to target 1, target 2 (and in fact target 3) within group 1 will also use caller.clone_1. However, since callee isn't cloned for target 2 the previous version wouldn't have saved this slot in the relocation array. (cherry picked from commit 76fc067185ce7737247122b5a1781f079a8f0711) --- src/llvm-multiversioning.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/llvm-multiversioning.cpp b/src/llvm-multiversioning.cpp index 57e90a9aa8056..afbe712f32c13 100644 --- a/src/llvm-multiversioning.cpp +++ b/src/llvm-multiversioning.cpp @@ -1052,7 +1052,7 @@ void CloneCtx::emit_metadata() idxs.push_back(baseidx); for (uint32_t j = 0; j < nfvars; j++) { auto base_f = grp->base_func(fvars[j]); - if (shared_relocs.count(j)) { + if (shared_relocs.count(j) || tgt->relocs.count(j)) { count++; idxs.push_back(jl_sysimg_tag_mask | j); auto f = map_get(*tgt->vmap, base_f, base_f); @@ -1060,7 +1060,7 @@ void CloneCtx::emit_metadata() } else if (auto f = map_get(*tgt->vmap, base_f)) { count++; - idxs.push_back(tgt->relocs.count(j) ? (jl_sysimg_tag_mask | j) : j); + idxs.push_back(j); offsets.push_back(get_ptrdiff32(cast(f), fbase)); } } From bfaabceb3d2ee32321bf2ba19338a75a7deab543 Mon Sep 17 00:00:00 2001 From: Simeon Schaub Date: Tue, 1 Mar 2022 17:09:38 -0500 Subject: [PATCH 13/46] fix #44328: method validation for opaque closures (#44335) I believe it's intentional that for these methods, the `sig` field is just ignored and always set to `Tuple`. Also fixes a lowering bug I discovered that would cause errors if `Union` was shadowed. I have verified that this fixes the reported warnings. Co-authored-by: Jameson Nash (cherry picked from commit 5deb503acb0d6dc2a801800ba2710b7e023db519) --- base/compiler/validation.jl | 5 ++++- src/julia-syntax.scm | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/base/compiler/validation.jl b/base/compiler/validation.jl index 77ee422b6ffcd..0931686184a2e 100644 --- a/base/compiler/validation.jl +++ b/base/compiler/validation.jl @@ -53,6 +53,7 @@ const NON_TOP_LEVEL_METHOD = "encountered `Expr` head `:method` in non-top-level const NON_TOP_LEVEL_GLOBAL = "encountered `Expr` head `:global` in non-top-level code (i.e. `nargs` > 0)" const SIGNATURE_NARGS_MISMATCH = "method signature does not match number of method arguments" const SLOTNAMES_NARGS_MISMATCH = "CodeInfo for method contains fewer slotnames than the number of method arguments" +const INVALID_SIGNATURE_OPAQUE_CLOSURE = "invalid signature of method for opaque closure - `sig` field must always be set to `Tuple`" struct InvalidCodeError <: Exception kind::String @@ -215,7 +216,9 @@ function validate_code!(errors::Vector{>:InvalidCodeError}, mi::Core.MethodInsta m = mi.def::Method mnargs = m.nargs n_sig_params = length((unwrap_unionall(m.sig)::DataType).parameters) - if (m.isva ? (n_sig_params < (mnargs - 1)) : (n_sig_params != mnargs)) + if m.is_for_opaque_closure + m.sig === Tuple || push!(errors, InvalidCodeError(INVALID_SIGNATURE_OPAQUE_CLOSURE, (m.sig, m.isva))) + elseif (m.isva ? (n_sig_params < (mnargs - 1)) : (n_sig_params != mnargs)) push!(errors, InvalidCodeError(SIGNATURE_NARGS_MISMATCH, (m.isva, n_sig_params, mnargs))) end end diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index 52bcb307ebe19..0f0e5c032d377 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -3862,7 +3862,7 @@ f(x) = yt(x) v))) cvs))) `(new_opaque_closure - ,(cadr e) (call (core apply_type) Union) (core Any) + ,(cadr e) (call (core apply_type) (core Union)) (core Any) (opaque_closure_method (null) ,nargs ,isva ,functionloc ,(convert-lambda lam2 (car (lam:args lam2)) #f '() (symbol-to-idx-map cvs))) ,@var-exprs)))) ((method) From dc8714a0b2063654588d80d60561fe55e3ca7b1f Mon Sep 17 00:00:00 2001 From: "Viral B. Shah" Date: Wed, 2 Mar 2022 23:10:02 -0500 Subject: [PATCH 14/46] Update BLAS.vendor() to return :lbt `vendor()` returns `:lbt` `libblas_name` and `liblapack_name` are set to "libblastrampoline" (cherry picked from commit bf6d9ded5a1c7787b19802ccc8d9cf8b3279e0d1) --- base/Base.jl | 4 ++++ stdlib/LinearAlgebra/src/blas.jl | 13 ++----------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/base/Base.jl b/base/Base.jl index a3fe44a2add86..cbfa5ede6aef9 100644 --- a/base/Base.jl +++ b/base/Base.jl @@ -161,6 +161,10 @@ end include(strcat((length(Core.ARGS)>=2 ? Core.ARGS[2] : ""), "build_h.jl")) # include($BUILDROOT/base/build_h.jl) include(strcat((length(Core.ARGS)>=2 ? Core.ARGS[2] : ""), "version_git.jl")) # include($BUILDROOT/base/version_git.jl) +# These used to be in build_h.jl and are retained for backwards compatibility +const libblas_name = "libblastrampoline" +const liblapack_name = "libblastrampoline" + # numeric operations include("hashing.jl") include("rounding.jl") diff --git a/stdlib/LinearAlgebra/src/blas.jl b/stdlib/LinearAlgebra/src/blas.jl index 9b5506e993ea8..46f7bd283ed87 100644 --- a/stdlib/LinearAlgebra/src/blas.jl +++ b/stdlib/LinearAlgebra/src/blas.jl @@ -79,6 +79,8 @@ using LinearAlgebra: BlasReal, BlasComplex, BlasFloat, BlasInt, DimensionMismatc include("lbt.jl") +vendor() = :lbt + """ get_config() @@ -89,17 +91,6 @@ Return an object representing the current `libblastrampoline` configuration. """ get_config() = lbt_get_config() -# We hard-lock `vendor()` to `openblas(64)` here to satisfy older code, but all new code should use -# `get_config()` since it is now possible to have multiple vendors loaded at once. -function vendor() - Base.depwarn("`vendor()` is deprecated, use `BLAS.get_config()` and inspect the output instead", :vendor; force=true) - if USE_BLAS64 - return :openblas64 - else - return :openblas - end -end - if USE_BLAS64 macro blasfunc(x) return Expr(:quote, Symbol(x, "64_")) From c25534e2015765cd5270bb3e751fe1607f5940d6 Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Thu, 3 Mar 2022 02:32:16 -0600 Subject: [PATCH 15/46] Fix memory error during precompilation (#44345) Fixes #44338 (cherry picked from commit b4ea0f7c4bd4b712e8bc2e86525a17be76f2cd01) --- src/dump.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/dump.c b/src/dump.c index 919bac8c82a07..c23533c81702f 100644 --- a/src/dump.c +++ b/src/dump.c @@ -272,6 +272,7 @@ static int has_backedge_to_worklist(jl_method_instance_t *mi, htable_t *visited) for (i = 0; i < n; i++) { jl_method_instance_t *be = (jl_method_instance_t*)jl_array_ptr_ref(mi->backedges, i); if (has_backedge_to_worklist(be, visited)) { + bp = ptrhash_bp(visited, mi); // re-acquire since rehashing might change the location *bp = (void*)((char*)HT_NOTFOUND + 2); // found return 1; } @@ -286,10 +287,10 @@ static size_t queue_external_mis(jl_array_t *list) { size_t i, n = 0; htable_t visited; - htable_new(&visited, 0); if (list) { assert(jl_is_array(list)); size_t n0 = jl_array_len(list); + htable_new(&visited, n0); for (i = 0; i < n0; i++) { jl_method_instance_t *mi = (jl_method_instance_t*)jl_array_ptr_ref(list, i); assert(jl_is_method_instance(mi)); @@ -2640,7 +2641,7 @@ JL_DLLEXPORT int jl_save_incremental(const char *fname, jl_array_t *worklist) arraylist_new(&reinit_list, 0); htable_new(&edges_map, 0); htable_new(&backref_table, 5000); - htable_new(&external_mis, 0); + htable_new(&external_mis, newly_inferred ? jl_array_len(newly_inferred) : 0); ptrhash_put(&backref_table, jl_main_module, (char*)HT_NOTFOUND + 1); backref_table_numel = 1; jl_idtable_type = jl_base_module ? jl_get_global(jl_base_module, jl_symbol("IdDict")) : NULL; From aa04f593602ca1461ee268b83e4873e28af44100 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Thu, 3 Mar 2022 10:49:13 -0500 Subject: [PATCH 16/46] asan,build: fix linker flags for -fsanitize builds (#44420) Fix #44361 Fix #42540 (cherry picked from commit 7324966ae735c4f1ca69e4c2d9e75a4a511032c7) --- .buildkite/pipelines/main/misc/sanitizers.yml | 1 - Make.inc | 18 ++++++------------ src/julia.expmap | 2 -- 3 files changed, 6 insertions(+), 15 deletions(-) diff --git a/.buildkite/pipelines/main/misc/sanitizers.yml b/.buildkite/pipelines/main/misc/sanitizers.yml index c8ebee340a48e..d5e83fb91cf68 100644 --- a/.buildkite/pipelines/main/misc/sanitizers.yml +++ b/.buildkite/pipelines/main/misc/sanitizers.yml @@ -21,7 +21,6 @@ steps: timeout_in_minutes: 120 if: | # We only run the `asan` job on Julia 1.8 and later. (pipeline.slug != "julia-release-1-dot-6") && (pipeline.slug != "julia-release-1-dot-7") - soft_fail: true # TODO: delete this line (and thus disallow failures) once JuliaLang/julia#42540 is fixed commands: | echo "--- Build julia-debug with ASAN" contrib/asan/build.sh ./tmp/test-asan -j$${JULIA_CPU_THREADS:?} debug diff --git a/Make.inc b/Make.inc index 9ea021e68c959..a95eab1ec1abe 100644 --- a/Make.inc +++ b/Make.inc @@ -483,9 +483,6 @@ endif endif ifeq ($(USEGCC),1) -ifeq ($(SANITIZE),1) -$(error Sanitizers are only supported with clang. Try setting SANITIZE=0) -endif CC := $(CROSS_COMPILE)gcc CXX := $(CROSS_COMPILE)g++ JCFLAGS := -std=gnu99 -pipe $(fPIC) -fno-strict-aliasing -D_FILE_OFFSET_BITS=64 @@ -519,6 +516,8 @@ JCPPFLAGS += -D_LARGEFILE_SOURCE -D_DARWIN_USE_64_BIT_INODE=1 endif endif +JLDFLAGS := + ifeq ($(USECCACHE), 1) # Expand CC, CXX and FC here already because we want the original definition and not the ccache version. CC_ARG := $(CC) @@ -1237,15 +1236,11 @@ IFUNC_DETECT_SRC := 'void (*f0(void))(void) { return (void(*)(void))0L; }; void ifeq (supported, $(shell echo $(IFUNC_DETECT_SRC) | $(CC) -Werror -x c - -S -o /dev/null > /dev/null 2>&1 && echo supported)) JCPPFLAGS += -DJULIA_HAS_IFUNC_SUPPORT=1 endif -JLDFLAGS := -Wl,-Bdynamic -ifneq ($(SANITIZE),1) -ifneq ($(SANITIZE_MEMORY),1) -ifneq ($(LLVM_SANITIZE),1) +JLDFLAGS += -Wl,-Bdynamic OSLIBS += -Wl,--version-script=$(JULIAHOME)/src/julia.expmap +ifneq ($(SANITIZE),1) JLDFLAGS += -Wl,-no-undefined endif -endif -endif ifeq (-Bsymbolic-functions, $(shell $(LD) --help | grep -o -e "-Bsymbolic-functions")) JLIBLDFLAGS := -Wl,-Bsymbolic-functions else @@ -1256,7 +1251,7 @@ JLIBLDFLAGS := endif ifeq ($(OS), FreeBSD) -JLDFLAGS := -Wl,-Bdynamic +JLDFLAGS += -Wl,-Bdynamic OSLIBS += -lelf -lkvm -lrt -lpthread -latomic # Tweak order of libgcc_s in DT_NEEDED, @@ -1274,7 +1269,6 @@ SHLIB_EXT := dylib OSLIBS += -framework CoreFoundation WHOLE_ARCHIVE := -Xlinker -all_load NO_WHOLE_ARCHIVE := -JLDFLAGS := HAVE_SSP := 1 JLIBLDFLAGS := -Wl,-compatibility_version,$(SOMAJOR) -Wl,-current_version,$(JULIA_MAJOR_VERSION).$(JULIA_MINOR_VERSION).$(JULIA_PATCH_VERSION) endif @@ -1283,7 +1277,7 @@ ifeq ($(OS), WINNT) HAVE_SSP := 1 OSLIBS += -Wl,--export-all-symbols -Wl,--version-script=$(JULIAHOME)/src/julia.expmap \ $(NO_WHOLE_ARCHIVE) -lpsapi -lkernel32 -lws2_32 -liphlpapi -lwinmm -ldbghelp -luserenv -lsecur32 -latomic -JLDFLAGS := -Wl,--stack,8388608 +JLDFLAGS += -Wl,--stack,8388608 ifeq ($(ARCH),i686) JLDFLAGS += -Wl,--large-address-aware endif diff --git a/src/julia.expmap b/src/julia.expmap index 558dfec6bd260..2d801dceae044 100644 --- a/src/julia.expmap +++ b/src/julia.expmap @@ -1,7 +1,5 @@ { global: - __asan*; - __tsan*; pthread*; __stack_chk_guard; asprintf; From 1cd27ca859db00c6a0c37608028aaed40dc5e409 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Thu, 3 Mar 2022 10:49:31 -0500 Subject: [PATCH 17/46] add jl_egal and jl_gc_safepoint back to exports list (#44419) Simple oversight when these were turned into macros. I could not find any others that seemed applicable, so just these two appeared to need fixing right now. Fix #44373 (cherry picked from commit 8eb872c159f608640b25bf60a6952556f955758b) --- src/jl_exported_funcs.inc | 54 ++++++++++++++++++++------------------- src/jlapi.c | 9 +++++-- src/julia.h | 2 ++ 3 files changed, 37 insertions(+), 28 deletions(-) diff --git a/src/jl_exported_funcs.inc b/src/jl_exported_funcs.inc index 7748809dcdf05..d63500fe21736 100644 --- a/src/jl_exported_funcs.inc +++ b/src/jl_exported_funcs.inc @@ -21,6 +21,10 @@ XX(jl_apply_type2) \ XX(jl_argument_datatype) \ XX(jl_argument_method_table) \ + XX(jl_arraylen) \ + XX(jl_arrayref) \ + XX(jl_arrayset) \ + XX(jl_arrayunset) \ XX(jl_array_cconvert_cstring) \ XX(jl_array_copy) \ XX(jl_array_del_at) \ @@ -31,19 +35,15 @@ XX(jl_array_grow_beg) \ XX(jl_array_grow_end) \ XX(jl_array_isassigned) \ - XX(jl_arraylen) \ XX(jl_array_ptr) \ XX(jl_array_ptr_1d_append) \ XX(jl_array_ptr_1d_push) \ XX(jl_array_ptr_copy) \ XX(jl_array_rank) \ - XX(jl_arrayref) \ - XX(jl_arrayset) \ XX(jl_array_size) \ XX(jl_array_sizehint) \ XX(jl_array_to_string) \ XX(jl_array_typetagdata) \ - XX(jl_arrayunset) \ XX(jl_array_validate_dims) \ XX(jl_atexit_hook) \ XX(jl_atomic_bool_cmpswap_bits) \ @@ -85,8 +85,8 @@ XX(jl_call1) \ XX(jl_call2) \ XX(jl_call3) \ - XX(jl_call_in_typeinf_world) \ XX(jl_calloc) \ + XX(jl_call_in_typeinf_world) \ XX(jl_capture_interp_frame) \ XX(jl_ceil_llvm) \ XX(jl_ceil_llvm_withtype) \ @@ -115,6 +115,7 @@ XX(jl_dlopen) \ XX(jl_dlsym) \ XX(jl_dump_host_cpu) \ + XX(jl_egal) \ XX(jl_egal__bits) \ XX(jl_egal__special) \ XX(jl_eh_restore_state) \ @@ -131,15 +132,14 @@ XX(jl_error) \ XX(jl_errorf) \ XX(jl_eval_string) \ - XX(jl_exception_clear) \ XX(jl_exceptionf) \ + XX(jl_exception_clear) \ XX(jl_exception_occurred) \ XX(jl_excstack_state) \ XX(jl_exit) \ 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) \ @@ -150,11 +150,11 @@ XX(jl_gc_add_finalizer) \ XX(jl_gc_add_finalizer_th) \ XX(jl_gc_add_ptr_finalizer) \ + XX(jl_gc_allocobj) \ XX(jl_gc_alloc_0w) \ XX(jl_gc_alloc_1w) \ XX(jl_gc_alloc_2w) \ XX(jl_gc_alloc_3w) \ - XX(jl_gc_allocobj) \ XX(jl_gc_alloc_typed) \ XX(jl_gc_big_alloc) \ XX(jl_gc_collect) \ @@ -184,6 +184,7 @@ XX(jl_gc_pool_alloc) \ XX(jl_gc_queue_multiroot) \ XX(jl_gc_queue_root) \ + XX(jl_gc_safepoint) \ XX(jl_gc_schedule_foreign_sweepfunc) \ XX(jl_gc_set_cb_notify_external_alloc) \ XX(jl_gc_set_cb_notify_external_free) \ @@ -198,6 +199,9 @@ XX(jl_generic_function_def) \ XX(jl_gensym) \ XX(jl_getallocationgranularity) \ + XX(jl_getnameinfo) \ + XX(jl_getpagesize) \ + XX(jl_getpid) \ XX(jl_get_ARCH) \ XX(jl_get_backtrace) \ XX(jl_get_binding) \ @@ -224,14 +228,11 @@ XX(jl_get_module_infer) \ XX(jl_get_module_of_binding) \ XX(jl_get_module_optlevel) \ - XX(jl_getnameinfo) \ XX(jl_get_next_task) \ XX(jl_get_nth_field) \ XX(jl_get_nth_field_checked) \ XX(jl_get_nth_field_noalloc) \ - XX(jl_getpagesize) \ XX(jl_get_pgcstack) \ - XX(jl_getpid) \ XX(jl_get_ptls_states) \ XX(jl_get_root_symbol) \ XX(jl_get_safe_restore) \ @@ -255,19 +256,19 @@ XX(jl_idtable_rehash) \ XX(jl_infer_thunk) \ XX(jl_init) \ - XX(jl_init__threading) \ + XX(jl_init_options) \ XX(jl_init_restored_modules) \ XX(jl_init_with_image) \ XX(jl_init_with_image__threading) \ - XX(jl_init_options) \ + XX(jl_init__threading) \ XX(jl_install_sigint_handler) \ XX(jl_instantiate_type_in_env) \ XX(jl_instantiate_unionall) \ XX(jl_intersect_types) \ - XX(jl_in_threaded_region) \ XX(jl_intrinsic_name) \ XX(jl_invoke) \ XX(jl_invoke_api) \ + XX(jl_in_threaded_region) \ XX(jl_iolock_begin) \ XX(jl_iolock_end) \ XX(jl_ios_buffer_n) \ @@ -280,6 +281,8 @@ XX(jl_ir_slotflag) \ XX(jl_isa) \ XX(jl_isa_compileable_sig) \ + XX(jl_islayout_inline) \ + XX(jl_istopmod) \ XX(jl_is_binding_deprecated) \ XX(jl_is_char_signed) \ XX(jl_is_const) \ @@ -288,12 +291,10 @@ XX(jl_is_imported) \ XX(jl_is_initialized) \ XX(jl_is_in_pure_context) \ - XX(jl_islayout_inline) \ XX(jl_is_memdebug) \ XX(jl_is_not_broken_subtype) \ XX(jl_is_operator) \ XX(jl_is_task_started) \ - XX(jl_istopmod) \ XX(jl_is_unary_and_binary_operator) \ XX(jl_is_unary_operator) \ XX(jl_lazy_load_and_lookup) \ @@ -336,8 +337,8 @@ XX(jl_nb_available) \ XX(jl_new_array) \ XX(jl_new_bits) \ - XX(jl_new_code_info_uninit) \ XX(jl_new_codeinst) \ + XX(jl_new_code_info_uninit) \ XX(jl_new_datatype) \ XX(jl_new_foreign_type) \ XX(jl_new_method_instance_uninit) \ @@ -347,14 +348,14 @@ XX(jl_new_primitivetype) \ XX(jl_new_struct) \ XX(jl_new_structt) \ - XX(jl_new_struct_uninit) \ XX(jl_new_structv) \ + XX(jl_new_struct_uninit) \ XX(jl_new_task) \ XX(jl_new_typename_in) \ XX(jl_new_typevar) \ XX(jl_next_from_addrinfo) \ - XX(jl_no_exc_handler) \ XX(jl_normalize_to_compilable_sig) \ + XX(jl_no_exc_handler) \ XX(jl_object_id) \ XX(jl_object_id_) \ XX(jl_obvious_subtype) \ @@ -372,8 +373,8 @@ XX(jl_pop_handler) \ XX(jl_preload_sysimg_so) \ XX(jl_prepend_cwd) \ - XX(jl_print_backtrace) \ XX(jl_printf) \ + XX(jl_print_backtrace) \ XX(jl_process_events) \ XX(jl_profile_clear_data) \ XX(jl_profile_delay_nsec) \ @@ -394,6 +395,7 @@ XX(jl_realloc) \ XX(jl_register_newmeth_tracer) \ XX(jl_reshape_array) \ + XX(jl_resolve_globals_in_ir) \ XX(jl_restore_excstack) \ XX(jl_restore_incremental) \ XX(jl_restore_incremental_from_buf) \ @@ -472,18 +474,18 @@ XX(jl_tty_set_mode) \ XX(jl_tupletype_fill) \ XX(jl_typeassert) \ + XX(jl_typeinf_begin) \ + XX(jl_typeinf_end) \ + XX(jl_typename_str) \ + XX(jl_typeof_str) \ + XX(jl_types_equal) \ XX(jl_type_equality_is_identity) \ XX(jl_type_error) \ XX(jl_type_error_rt) \ - XX(jl_typeinf_begin) \ - XX(jl_typeinf_end) \ XX(jl_type_intersection) \ XX(jl_type_intersection_with_env) \ XX(jl_type_morespecific) \ XX(jl_type_morespecific_no_subtype) \ - XX(jl_typename_str) \ - XX(jl_typeof_str) \ - XX(jl_types_equal) \ XX(jl_type_union) \ XX(jl_type_unionall) \ XX(jl_unbox_bool) \ @@ -499,8 +501,8 @@ XX(jl_unbox_uint8) \ XX(jl_unbox_uint8pointer) \ XX(jl_unbox_voidpointer) \ - XX(jl_uncompress_argname_n) \ XX(jl_uncompress_argnames) \ + XX(jl_uncompress_argname_n) \ XX(jl_uncompress_ir) \ XX(jl_undefined_var_error) \ XX(jl_value_ptr) \ diff --git a/src/jlapi.c b/src/jlapi.c index 3ab01c5def7f4..18a98d943187b 100644 --- a/src/jlapi.c +++ b/src/jlapi.c @@ -411,7 +411,7 @@ JL_DLLEXPORT const char *jl_git_commit(void) return commit; } -// Create function versions of some useful macros +// Create function versions of some useful macros for GDB or FFI use JL_DLLEXPORT jl_taggedvalue_t *(jl_astaggedvalue)(jl_value_t *v) { return jl_astaggedvalue(v); @@ -432,6 +432,11 @@ JL_DLLEXPORT jl_value_t *(jl_get_fieldtypes)(jl_value_t *v) return (jl_value_t*)jl_get_fieldtypes((jl_datatype_t*)v); } +JL_DLLEXPORT int ijl_egal(jl_value_t *a, jl_value_t *b) +{ + return jl_egal(a, b); +} + #ifndef __clang_gcanalyzer__ JL_DLLEXPORT int8_t (jl_gc_unsafe_enter)(void) @@ -459,7 +464,7 @@ JL_DLLEXPORT void (jl_gc_safe_leave)(int8_t state) } #endif -JL_DLLEXPORT void (jl_gc_safepoint)(void) +JL_DLLEXPORT void jl_gc_safepoint(void) { jl_task_t *ct = jl_current_task; jl_gc_safepoint_(ct->ptls); diff --git a/src/julia.h b/src/julia.h index afb0d00630dbd..2d51de2f3ed9b 100644 --- a/src/julia.h +++ b/src/julia.h @@ -7,6 +7,7 @@ #include "jl_internal_funcs.inc" #undef jl_setjmp #undef jl_longjmp +#undef jl_egal #endif #include "julia_fasttls.h" @@ -925,6 +926,7 @@ STATIC_INLINE void jl_gc_multi_wb(const void *parent, const jl_value_t *ptr) JL_ JL_DLLEXPORT void *jl_gc_managed_malloc(size_t sz); JL_DLLEXPORT void *jl_gc_managed_realloc(void *d, size_t sz, size_t oldsz, int isaligned, jl_value_t *owner); +JL_DLLEXPORT void jl_gc_safepoint(void); // object accessors ----------------------------------------------------------- From 4a30b380fbb3314461706b6b1b3ea6d6fd47e8db Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Thu, 3 Mar 2022 08:45:49 -0800 Subject: [PATCH 18/46] Clarify the behavior of `@threads for` (#44168) * Clarify the behavior of `@threads for` Co-authored-by: Ian Butterworth (cherry picked from commit 2f67b51c70280cf7f0f2da5de2e7769da0d49869) --- base/threadingconstructs.jl | 92 +++++++++++++++++++++++++------------ 1 file changed, 62 insertions(+), 30 deletions(-) diff --git a/base/threadingconstructs.jl b/base/threadingconstructs.jl index 9ed416caec2a6..a3413701fb7de 100644 --- a/base/threadingconstructs.jl +++ b/base/threadingconstructs.jl @@ -99,46 +99,82 @@ end """ Threads.@threads [schedule] for ... end -A macro to parallelize a `for` loop to run with multiple threads. Splits the iteration -space among multiple tasks and runs those tasks on threads according to a scheduling -policy. -A barrier is placed at the end of the loop which waits for all tasks to finish -execution. - -The `schedule` argument can be used to request a particular scheduling policy. - -Except for `:static` scheduling, how the iterations are assigned to tasks, and how the tasks -are assigned to the worker threads is undefined. The exact assignments can be different -for each execution. The scheduling option is a hint. The loop body code (including any code -transitively called from it) must not make assumptions about the distribution of iterations -to tasks or the worker thread in which they are executed. The loop body for each iteration -must be able to make forward progress independent of other iterations and be free from data -races. As such, synchronizations across iterations may deadlock. +A macro to execute a `for` loop in parallel. The iteration space is distributed to +coarse-grained tasks. This policy can be specified by the `schedule` argument. The +execution of the loop waits for the evaluation of all iterations. + +See also: [`@spawn`](@ref Threads.@spawn) and +`pmap` in [`Distributed`](@ref man-distributed). + +# Extended help + +## Semantics + +Unless stronger guarantees are specified by the scheduling option, the loop executed by +`@threads` macro have the following semantics. + +The `@threads` macro executes the loop body in an unspecified order and potentially +concurrently. It does not specify the exact assignments of the tasks and the worker threads. +The assignments can be different for each execution. The loop body code (including any code +transitively called from it) must not make any assumptions about the distribution of +iterations to tasks or the worker thread in which they are executed. The loop body for each +iteration must be able to make forward progress independent of other iterations and be free +from data races. As such, invalid synchronizations across iterations may deadlock while +unsynchronized memory accesses may result in undefined behavior. For example, the above conditions imply that: - The lock taken in an iteration *must* be released within the same iteration. - Communicating between iterations using blocking primitives like `Channel`s is incorrect. -- Write only to locations not shared across iterations (unless a lock or atomic operation is used). +- Write only to locations not shared across iterations (unless a lock or atomic operation is + used). +- The value of [`threadid()`](@ref Threads.threadid) may change even within a single + iteration. -Schedule options are: -- `:dynamic` (default) will schedule iterations dynamically to available worker threads, - assuming that the workload for each iteration is uniform. -- `:static` creates one task per thread and divides the iterations equally among - them, assigning each task specifically to each thread. - Specifying `:static` is an error if used from inside another `@threads` loop - or from a thread other than 1. +## Schedulers -Without the scheduler argument, the exact scheduling is unspecified and varies across Julia releases. +Without the scheduler argument, the exact scheduling is unspecified and varies across Julia +releases. Currently, `:dynamic` is used when the scheduler is not specified. !!! compat "Julia 1.5" The `schedule` argument is available as of Julia 1.5. +### `:dynamic` (default) + +`:dynamic` scheduler executes iterations dynamically to available worker threads. Current +implementation assumes that the workload for each iteration is uniform. However, this +assumption may be removed in the future. + +This scheduling option is merely a hint to the underlying execution mechanism. However, a +few properties can be expected. The number of `Task`s used by `:dynamic` scheduler is +bounded by a small constant multiple of the number of available worker threads +([`nthreads()`](@ref Threads.nthreads)). Each task processes contiguous regions of the +iteration space. Thus, `@threads :dynamic for x in xs; f(x); end` is typically more +efficient than `@sync for x in xs; @spawn f(x); end` if `length(xs)` is significantly +larger than the number of the worker threads and the run-time of `f(x)` is relatively +smaller than the cost of spawning and synchronizaing a task (typically less than 10 +microseconds). + !!! compat "Julia 1.8" The `:dynamic` option for the `schedule` argument is available and the default as of Julia 1.8. -For example, an illustration of the different scheduling strategies where `busywait` -is a non-yielding timed loop that runs for a number of seconds. +### `:static` + +`:static` scheduler creates one task per thread and divides the iterations equally among +them, assigning each task specifically to each thread. In particular, the value of +[`threadid()`](@ref Threads.threadid) is guranteed to be constant within one iteration. +Specifying `:static` is an error if used from inside another `@threads` loop or from a +thread other than 1. + +!!! note + `:static` scheduling exists for supporting transition of code written before Julia 1.3. + In newly written library functions, `:static` scheduling is discouraged because the + functions using this option cannot be called from arbitrary worker threads. + +## Example + +To illustrate of the different scheduling strategies, consider the following function +`busywait` containing a non-yielding timed loop that runs for a given number of seconds. ```julia-repl julia> function busywait(seconds) @@ -166,10 +202,6 @@ julia> @time begin The `:dynamic` example takes 2 seconds since one of the non-occupied threads is able to run two of the 1-second iterations to complete the for loop. - -See also: [`@spawn`](@ref Threads.@spawn), [`nthreads()`](@ref Threads.nthreads), -[`threadid()`](@ref Threads.threadid), `pmap` in [`Distributed`](@ref man-distributed), -`BLAS.set_num_threads` in [`LinearAlgebra`](@ref man-linalg). """ macro threads(args...) na = length(args) From f2539a0d04130886f6c6428dd36f6f1f91bc6fb1 Mon Sep 17 00:00:00 2001 From: Oscar Smith Date: Thu, 3 Mar 2022 16:32:49 -0500 Subject: [PATCH 19/46] fix error show edge case (#44319) * fix errors Co-authored-by: Simeon Schaub (cherry picked from commit a9d8c859c71c7ed4aaa370ae659eba8eea263f4d) --- base/errorshow.jl | 2 +- test/error.jl | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/base/errorshow.jl b/base/errorshow.jl index 9441292e2c6ee..e56a095d832fd 100644 --- a/base/errorshow.jl +++ b/base/errorshow.jl @@ -508,7 +508,7 @@ function show_method_candidates(io::IO, ex::MethodError, @nospecialize kwargs=() end print(iob, ")") show_method_params(iob0, tv) - file, line = functionloc(method) + file, line = updated_methodloc(method) if file === nothing file = string(method.file) end diff --git a/test/error.jl b/test/error.jl index e9d011e382a61..9b87cb6fff185 100644 --- a/test/error.jl +++ b/test/error.jl @@ -86,3 +86,13 @@ end e = SystemError("fail") @test e.extrainfo === nothing end + +@testset "MethodError for methods without line numbers" begin + try + eval(Expr(:function, :(f44319()), 0)) + f44319(1) + catch e + s = sprint(showerror, e) + @test s == "MethodError: no method matching f44319(::Int64)\nClosest candidates are:\n f44319() at none:0" + end +end From c39510e8f1cb49aaf466165368f62ce2129cc4bb Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Thu, 3 Mar 2022 21:42:46 -0500 Subject: [PATCH 20/46] optimizer: bail out of inlining if ir_inline_unionsplit will fail (#44416) Intersection cannot deal with this `metharg`, so it does not simplify the type at all when handling this case. This can cause us to run into an assertion later, where we assume the intersection of a non-Varags type will always return a simple DataType without Varargs. Fixes #44238 atype = Tuple{typeof(Base.similar), Tuple{Union{Polyhedra.Polyhedron{T}, Polyhedra.Representation{T}} where T}, Array{_A, 1} where _A, Array{_C, 1} where _C, Array{_B, 1} where _B} metharg = Tuple{typeof(Base.similar), Tuple{Vararg{Union{Polyhedra.Polyhedron{T}, Polyhedra.Representation{T}} where T}}, Vararg{Union{Union{AbstractArray{var"#s14", 1}, Polyhedra.AbstractRepIterator{var"#s13", var"#s14"} where var"#s13", Polyhedra.AllRepIterator{var"#s14", var"#s14", LinElemT, LRT, RT} where RT<:Polyhedra.AbstractRepIterator{var"#s14", var"#s14"} where LRT<:Polyhedra.AbstractRepIterator{var"#s14", LinElemT} where LinElemT where var"#s14"} where var"#s14"<:(Polyhedra.HyperPlane{T, AT} where AT<:AbstractArray{T, 1}), Union{AbstractArray{var"#s14", 1}, Polyhedra.AbstractRepIterator{var"#s13", var"#s14"} where var"#s13", Polyhedra.AllRepIterator{var"#s14", var"#s14", LinElemT, LRT, RT} where RT<:Polyhedra.AbstractRepIterator{var"#s14", var"#s14"} where LRT<:Polyhedra.AbstractRepIterator{var"#s14", LinElemT} where LinElemT where var"#s14"} where var"#s14"<:(Polyhedra.HalfSpace{T, AT} where AT<:AbstractArray{T, 1}), Union{AbstractArray{var"#s14", 1}, Polyhedra.AbstractRepIterator{var"#s13", var"#s14"} where var"#s13", Polyhedra.AllRepIterator{var"#s14", var"#s14", LinElemT, LRT, RT} where RT<:Polyhedra.AbstractRepIterator{var"#s14", var"#s14"} where LRT<:Polyhedra.AbstractRepIterator{var"#s14", LinElemT} where LinElemT where var"#s14"} where var"#s14"<:AbstractArray{T, 1}, Union{AbstractArray{var"#s14", 1}, Polyhedra.AbstractRepIterator{var"#s13", var"#s14"} where var"#s13", Polyhedra.AllRepIterator{var"#s14", var"#s14", LinElemT, LRT, RT} where RT<:Polyhedra.AbstractRepIterator{var"#s14", var"#s14"} where LRT<:Polyhedra.AbstractRepIterator{var"#s14", LinElemT} where LinElemT where var"#s14"} where var"#s14"<:(Polyhedra.Line{T, AT} where AT<:AbstractArray{T, 1}), Union{AbstractArray{var"#s14", 1}, Polyhedra.AbstractRepIterator{var"#s13", var"#s14"} where var"#s13", Polyhedra.AllRepIterator{var"#s14", var"#s14", LinElemT, LRT, RT} where RT<:Polyhedra.AbstractRepIterator{var"#s14", var"#s14"} where LRT<:Polyhedra.AbstractRepIterator{var"#s14", LinElemT} where LinElemT where var"#s14"} where var"#s14"<:(Polyhedra.Ray{T, AT} where AT<:AbstractArray{T, 1})} where T}} Currently `typeintersection(atype, metharg) === metharg` (cherry picked from commit ffc5ffa40826a174f08c5710f640990884f8357c) --- base/compiler/ssair/inlining.jl | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/base/compiler/ssair/inlining.jl b/base/compiler/ssair/inlining.jl index fc3c3a60115e6..510c3bdaf5b03 100644 --- a/base/compiler/ssair/inlining.jl +++ b/base/compiler/ssair/inlining.jl @@ -820,9 +820,9 @@ end function analyze_method!(match::MethodMatch, argtypes::Vector{Any}, flag::UInt8, state::InliningState) method = match.method - methsig = method.sig + spec_types = match.spec_types - # Check that we habe the correct number of arguments + # Check that we have the correct number of arguments na = Int(method.nargs) npassedargs = length(argtypes) if na != npassedargs && !(na > 0 && method.isva) @@ -832,6 +832,13 @@ function analyze_method!(match::MethodMatch, argtypes::Vector{Any}, # call this function return nothing end + if !match.fully_covers + # type-intersection was not able to give us a simple list of types, so + # ir_inline_unionsplit won't be able to deal with inlining this + if !(spec_types isa DataType && length(spec_types.parameters) == length(argtypes) && !isvarargtype(spec_types.parameters[end])) + return nothing + end + end # Bail out if any static parameters are left as TypeVar validate_sparams(match.sparams) || return nothing From 5f6632780bd6298df574e824feafec8fe6f3775c Mon Sep 17 00:00:00 2001 From: KristofferC Date: Fri, 4 Mar 2022 08:58:28 +0100 Subject: [PATCH 21/46] Revert "Update BLAS.vendor() to return :lbt" This reverts commit e54b04a1996270bf8941a3e1f6c45808022108a9. --- base/Base.jl | 4 ---- stdlib/LinearAlgebra/src/blas.jl | 13 +++++++++++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/base/Base.jl b/base/Base.jl index cbfa5ede6aef9..a3fe44a2add86 100644 --- a/base/Base.jl +++ b/base/Base.jl @@ -161,10 +161,6 @@ end include(strcat((length(Core.ARGS)>=2 ? Core.ARGS[2] : ""), "build_h.jl")) # include($BUILDROOT/base/build_h.jl) include(strcat((length(Core.ARGS)>=2 ? Core.ARGS[2] : ""), "version_git.jl")) # include($BUILDROOT/base/version_git.jl) -# These used to be in build_h.jl and are retained for backwards compatibility -const libblas_name = "libblastrampoline" -const liblapack_name = "libblastrampoline" - # numeric operations include("hashing.jl") include("rounding.jl") diff --git a/stdlib/LinearAlgebra/src/blas.jl b/stdlib/LinearAlgebra/src/blas.jl index 46f7bd283ed87..9b5506e993ea8 100644 --- a/stdlib/LinearAlgebra/src/blas.jl +++ b/stdlib/LinearAlgebra/src/blas.jl @@ -79,8 +79,6 @@ using LinearAlgebra: BlasReal, BlasComplex, BlasFloat, BlasInt, DimensionMismatc include("lbt.jl") -vendor() = :lbt - """ get_config() @@ -91,6 +89,17 @@ Return an object representing the current `libblastrampoline` configuration. """ get_config() = lbt_get_config() +# We hard-lock `vendor()` to `openblas(64)` here to satisfy older code, but all new code should use +# `get_config()` since it is now possible to have multiple vendors loaded at once. +function vendor() + Base.depwarn("`vendor()` is deprecated, use `BLAS.get_config()` and inspect the output instead", :vendor; force=true) + if USE_BLAS64 + return :openblas64 + else + return :openblas + end +end + if USE_BLAS64 macro blasfunc(x) return Expr(:quote, Symbol(x, "64_")) From ed0eb780ca6d0ef4ac233f8adeff7d8510b23275 Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Fri, 4 Mar 2022 12:36:58 -0600 Subject: [PATCH 22/46] Fix htable cleanup (#44446) This htable was allocated conditionally, so the cleanup must be too. Co-authored by: Jameson Nash (cherry picked from commit c3d7edc4cdba65ca27bd4f4b2f55730ebfba9f88) --- src/dump.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dump.c b/src/dump.c index c23533c81702f..956466ac765b2 100644 --- a/src/dump.c +++ b/src/dump.c @@ -312,8 +312,8 @@ static size_t queue_external_mis(jl_array_t *list) } } } + htable_free(&visited); } - htable_free(&visited); return n; } From 5b14e0747d5c9144ee15fb65eace94bd75916c89 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Sun, 6 Mar 2022 00:02:44 -0500 Subject: [PATCH 23/46] [RemoveAddrspaces] make MappedTypes non-static (#44453) (cherry picked from commit 610fc20640b93c5a41bbedc3483a031886e983e7) --- src/llvm-remove-addrspaces.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/llvm-remove-addrspaces.cpp b/src/llvm-remove-addrspaces.cpp index 9b3631e264124..bcc03bd4d3fb3 100644 --- a/src/llvm-remove-addrspaces.cpp +++ b/src/llvm-remove-addrspaces.cpp @@ -105,10 +105,9 @@ class AddrspaceRemoveTypeRemapper : public ValueMapTypeRemapper { } private: - static DenseMap MappedTypes; + DenseMap MappedTypes; }; -DenseMap AddrspaceRemoveTypeRemapper::MappedTypes; class AddrspaceRemoveValueMaterializer : public ValueMaterializer { ValueToValueMapTy &VM; From 885eccf3a866eda1d497fadcfd21e5b924d877b5 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Sun, 6 Mar 2022 21:30:53 -0500 Subject: [PATCH 24/46] Fix intermittent `threaded loop executed in order` test warning (#44479) (cherry picked from commit cfb0d465e0858eabb8591668d1320e00f6fc964e) --- test/threads_exec.jl | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/test/threads_exec.jl b/test/threads_exec.jl index 63e3be1b88cb7..ca8ec03b685e4 100644 --- a/test/threads_exec.jl +++ b/test/threads_exec.jl @@ -70,7 +70,23 @@ end # parallel loop with parallel atomic addition function threaded_loop(a, r, x) + counter = Threads.Atomic{Int}(min(Threads.nthreads(), length(r))) @threads for i in r + # synchronize the start given that each partition is started sequentially, + # meaning that without the wait, if the loop is too fast the iteration can happen in order + if counter[] != 0 + Threads.atomic_sub!(counter, 1) + spins = 0 + while counter[] != 0 + GC.safepoint() + ccall(:jl_cpu_pause, Cvoid, ()) + spins += 1 + if spins > 500_000_000 # about 10 seconds + @warn "Failed wait for all workers. Unfinished rogue tasks occupying worker threads?" + break + end + end + end j = i - firstindex(r) + 1 a[j] = 1 + atomic_add!(x, 1) end @@ -83,18 +99,13 @@ function test_threaded_loop_and_atomic_add() a = zeros(Int, n) threaded_loop(a,r,x) found = zeros(Bool,n) - was_inorder = true for i=1:length(a) - was_inorder &= a[i]==i found[a[i]] = true end @test x[] == n # Next test checks that all loop iterations ran, # and were unique (via pigeon-hole principle). @test !(false in found) - if was_inorder && nthreads() > 1 - println(stderr, "Warning: threaded loop executed in order") - end end end From 406b29392e776e547d06d54ee546ccf5fd62be39 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Sun, 6 Mar 2022 07:59:06 -0500 Subject: [PATCH 25/46] =?UTF-8?q?Fix=20or=20suppress=20some=20noisy=20test?= =?UTF-8?q?s=20=F0=9F=8F=8C=EF=B8=8F=E2=80=8D=E2=99=82=EF=B8=8F=20(#44444)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit d9714655cab409db4d57030cb403f3f553dc6453) --- .../md5 | 1 + .../sha512 | 1 + .../md5 | 1 - .../sha512 | 1 - stdlib/Artifacts/test/refresh_artifacts.jl | 4 ++-- stdlib/LazyArtifacts/test/runtests.jl | 16 ++++++++++------ stdlib/LibGit2/test/bad_ca_roots.jl | 8 +++++--- stdlib/REPL/test/repl.jl | 2 ++ stdlib/SHA.version | 2 +- test/backtrace.jl | 2 +- test/boundscheck_exec.jl | 4 +++- test/deprecation_exec.jl | 17 ++++++++++------- test/loading.jl | 9 +++++---- test/misc.jl | 19 ++++++++++++++++--- test/secretbuffer.jl | 3 ++- test/specificity.jl | 5 +++++ test/syntax.jl | 10 +++++----- 17 files changed, 69 insertions(+), 36 deletions(-) create mode 100644 deps/checksums/SHA-2d1f84e6f8417a1a368de48318640d948b023e7a.tar.gz/md5 create mode 100644 deps/checksums/SHA-2d1f84e6f8417a1a368de48318640d948b023e7a.tar.gz/sha512 delete mode 100644 deps/checksums/SHA-57c3a8c8358021b7a58526364e6885768fd95de2.tar.gz/md5 delete mode 100644 deps/checksums/SHA-57c3a8c8358021b7a58526364e6885768fd95de2.tar.gz/sha512 diff --git a/deps/checksums/SHA-2d1f84e6f8417a1a368de48318640d948b023e7a.tar.gz/md5 b/deps/checksums/SHA-2d1f84e6f8417a1a368de48318640d948b023e7a.tar.gz/md5 new file mode 100644 index 0000000000000..f682cf3518658 --- /dev/null +++ b/deps/checksums/SHA-2d1f84e6f8417a1a368de48318640d948b023e7a.tar.gz/md5 @@ -0,0 +1 @@ +de53629eb0b1ce98ac6b245bdbf14e9d diff --git a/deps/checksums/SHA-2d1f84e6f8417a1a368de48318640d948b023e7a.tar.gz/sha512 b/deps/checksums/SHA-2d1f84e6f8417a1a368de48318640d948b023e7a.tar.gz/sha512 new file mode 100644 index 0000000000000..870098ef7aada --- /dev/null +++ b/deps/checksums/SHA-2d1f84e6f8417a1a368de48318640d948b023e7a.tar.gz/sha512 @@ -0,0 +1 @@ +71cdc58b03cc4f42f8c4b9c2353d6f94d77b4ac5c9d374387d435c57ba85e966f3be4e8c8447b34e184cb8e665c42b3cd2c9d9742c86f7fb5c71a85df5087966 diff --git a/deps/checksums/SHA-57c3a8c8358021b7a58526364e6885768fd95de2.tar.gz/md5 b/deps/checksums/SHA-57c3a8c8358021b7a58526364e6885768fd95de2.tar.gz/md5 deleted file mode 100644 index 1bcc55fb297fa..0000000000000 --- a/deps/checksums/SHA-57c3a8c8358021b7a58526364e6885768fd95de2.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -96d57bc32f4f9bb8c66117c96e6243fc diff --git a/deps/checksums/SHA-57c3a8c8358021b7a58526364e6885768fd95de2.tar.gz/sha512 b/deps/checksums/SHA-57c3a8c8358021b7a58526364e6885768fd95de2.tar.gz/sha512 deleted file mode 100644 index 7f6c994b2fbb7..0000000000000 --- a/deps/checksums/SHA-57c3a8c8358021b7a58526364e6885768fd95de2.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -7243eddcccb634910f35252f30b29fe44c348955039bea56546765ab828bddb575a87603e91c89bee2619ea6e45b606c23fab2c8f4fc28c910571800732201a9 diff --git a/stdlib/Artifacts/test/refresh_artifacts.jl b/stdlib/Artifacts/test/refresh_artifacts.jl index a70e13db1ee93..7078912c00072 100644 --- a/stdlib/Artifacts/test/refresh_artifacts.jl +++ b/stdlib/Artifacts/test/refresh_artifacts.jl @@ -12,11 +12,11 @@ let if meta isa Array for meta in meta get(meta, "lazy", false) && continue - ensure_artifact_installed(name, meta, toml; platform=unused) + ensure_artifact_installed(name, meta, toml; platform=unused, io = devnull) end else; meta::Dict get(meta, "lazy", false) && continue - ensure_artifact_installed(name, meta, toml; platform=unused) + ensure_artifact_installed(name, meta, toml; platform=unused, io = devnull) end end end diff --git a/stdlib/LazyArtifacts/test/runtests.jl b/stdlib/LazyArtifacts/test/runtests.jl index 5e3850caecf4c..53898082cd346 100644 --- a/stdlib/LazyArtifacts/test/runtests.jl +++ b/stdlib/LazyArtifacts/test/runtests.jl @@ -5,8 +5,10 @@ using Test mktempdir() do tempdir LazyArtifacts.Artifacts.with_artifacts_directory(tempdir) do - socrates_dir = artifact"socrates" - @test isdir(socrates_dir) + redirect_stderr(devnull) do + socrates_dir = artifact"socrates" + @test isdir(socrates_dir) + end ex = @test_throws ErrorException artifact"HelloWorldC" @test startswith(ex.value.msg, "Artifact \"HelloWorldC\" was not installed correctly. ") end @@ -18,10 +20,12 @@ end using Test mktempdir() do tempdir Artifacts.with_artifacts_directory(tempdir) do - socrates_dir = @test_logs( - (:warn, "using Pkg instead of using LazyArtifacts is deprecated"), - artifact"socrates") - @test isdir(socrates_dir) + redirect_stderr(devnull) do + socrates_dir = @test_logs( + (:warn, "using Pkg instead of using LazyArtifacts is deprecated"), + artifact"socrates") + @test isdir(socrates_dir) + end end end'`, dir=@__DIR__))) diff --git a/stdlib/LibGit2/test/bad_ca_roots.jl b/stdlib/LibGit2/test/bad_ca_roots.jl index e4ebdc709637a..4882065167bdb 100644 --- a/stdlib/LibGit2/test/bad_ca_roots.jl +++ b/stdlib/LibGit2/test/bad_ca_roots.jl @@ -9,7 +9,9 @@ using Test, LibGit2, NetworkOptions # if that changes, this may need to be adjusted const CAN_SET_CA_ROOTS_PATH = !Sys.isapple() && !Sys.iswindows() -@testset "empty CA roots file" begin +# Given this is a sub-processed test file, not using @testsets avoids +# leaking the report print into the Base test runner report +begin # empty CA roots file # these fail for different reasons on different platforms: # - on Apple & Windows you cannot set the CA roots path location # - on Linux & FreeBSD you you can but these are invalid files @@ -29,14 +31,14 @@ const CAN_SET_CA_ROOTS_PATH = !Sys.isapple() && !Sys.iswindows() end if CAN_SET_CA_ROOTS_PATH - @testset "non-empty but bad CA roots file" begin + begin # non-empty but bad CA roots file # should still be possible to initialize ENV["JULIA_SSL_CA_ROOTS_PATH"] = joinpath(@__DIR__, "bad_ca_roots.pem") @test LibGit2.ensure_initialized() === nothing end mktempdir() do dir repo_url = "https://github.com/JuliaLang/Example.jl" - @testset "HTTPS clone with bad CA roots fails" begin + begin # HTTPS clone with bad CA roots fails repo_path = joinpath(dir, "Example.HTTPS") c = LibGit2.CredentialPayload(allow_prompt=false, allow_git_helpers=false) redirect_stderr(devnull) diff --git a/stdlib/REPL/test/repl.jl b/stdlib/REPL/test/repl.jl index d711d0be5e243..05f583c807165 100644 --- a/stdlib/REPL/test/repl.jl +++ b/stdlib/REPL/test/repl.jl @@ -751,6 +751,7 @@ fake_repl() do stdin_write, stdout_read, repl @test readuntil(stdout_read, "end", keep=true) == "\n\r\e[7C α=1\n\r\e[7C β=2\n\r\e[7Cend" # Test switching repl modes + redirect_stdout(devnull) do # to suppress "foo" echoes sendrepl2("""\e[200~ julia> A = 1 1 @@ -775,6 +776,7 @@ fake_repl() do stdin_write, stdout_read, repl wait(c) @test Main.A == 1 @test Main.B == 2 + end # redirect_stdout # Close repl write(stdin_write, '\x04') diff --git a/stdlib/SHA.version b/stdlib/SHA.version index 312fbc55ea97c..f2242a336c6fe 100644 --- a/stdlib/SHA.version +++ b/stdlib/SHA.version @@ -1,4 +1,4 @@ SHA_BRANCH = master -SHA_SHA1 = 57c3a8c8358021b7a58526364e6885768fd95de2 +SHA_SHA1 = 2d1f84e6f8417a1a368de48318640d948b023e7a SHA_GIT_URL := https://github.com/JuliaCrypto/SHA.jl.git SHA_TAR_URL = https://api.github.com/repos/JuliaCrypto/SHA.jl/tarball/$1 diff --git a/test/backtrace.jl b/test/backtrace.jl index 3aebfec410f34..35b607137a5c2 100644 --- a/test/backtrace.jl +++ b/test/backtrace.jl @@ -184,7 +184,7 @@ end # issue 28618 let bt, found = false - @info "" + @debug "" bt = backtrace() for frame in map(lookup, bt) if frame[1].line == @__LINE__() - 2 && frame[1].file == Symbol(@__FILE__) diff --git a/test/boundscheck_exec.jl b/test/boundscheck_exec.jl index 71690c55faeca..715700e00378f 100644 --- a/test/boundscheck_exec.jl +++ b/test/boundscheck_exec.jl @@ -259,7 +259,9 @@ if bc_opt == bc_default || bc_opt == bc_off @test !occursin("arrayref(true", typed_40281) end -@testset "pass inbounds meta to getindex on CartesianIndices (#42115)" begin +# Given this is a sub-processed test file, not using @testsets avoids +# leaking the report print into the Base test runner report +begin # Pass inbounds meta to getindex on CartesianIndices (#42115) @inline getindex_42115(r, i) = @inbounds getindex(r, i) @inline getindex_42115(r, i, j) = @inbounds getindex(r, i, j) diff --git a/test/deprecation_exec.jl b/test/deprecation_exec.jl index efbb251daa1e0..7b73c874495ee 100644 --- a/test/deprecation_exec.jl +++ b/test/deprecation_exec.jl @@ -43,7 +43,9 @@ struct T21972 end end -@testset "@deprecate" begin +# Given this is a sub-processed test file, not using @testsets avoids +# leaking the report print into the Base test runner report +begin # @deprecate using .DeprecationTests using .Foo1234 @test foo1234(3) == 4 @@ -87,7 +89,7 @@ f24658() = depwarn24658() depwarn24658() = Base.firstcaller(backtrace(), :_func_not_found_) -@testset "firstcaller" begin +begin # firstcaller # issue #24658 @test eval(:(if true; f24658(); end)) == (Ptr{Cvoid}(0),StackTraces.UNKNOWN) end @@ -113,7 +115,7 @@ global_logger(prev_logger) #------------------------------------------------------------------------------- # BEGIN 0.7 deprecations -@testset "parser syntax deprecations" begin +begin # parser syntax deprecations # #15524 # @test (@test_deprecated Meta.parse("for a=b f() end")) == :(for a=b; f() end) @test_broken length(Test.collect_test_logs(()->Meta.parse("for a=b f() end"))[1]) > 0 @@ -121,10 +123,11 @@ end # END 0.7 deprecations -@testset "tuple indexed by float deprecation" begin +begin # tuple indexed by float deprecation @test_deprecated getindex((1,), 1.0) === 1 @test_deprecated getindex((1,2), 2.0) === 2 - @test_throws Exception getindex((), 1.0) - @test_throws Exception getindex((1,2), 0.0) - @test_throws Exception getindex((1,2), -1.0) + @test Base.JLOptions().depwarn == 1 + @test_throws Exception @test_warn r"`getindex(t::Tuple, i::Real)` is deprecated" getindex((), 1.0) + @test_throws Exception @test_warn r"`getindex(t::Tuple, i::Real)` is deprecated" getindex((1,2), 0.0) + @test_throws Exception @test_warn r"`getindex(t::Tuple, i::Real)` is deprecated" getindex((1,2), -1.0) end diff --git a/test/loading.jl b/test/loading.jl index dc8a9103fbbe5..7dd6ce2935be6 100644 --- a/test/loading.jl +++ b/test/loading.jl @@ -234,6 +234,7 @@ append!(empty!(DEPOT_PATH), [mktempdir(), joinpath(@__DIR__, "depot")]) @test watcher_counter[] == 0 @test_logs (:error, r"active project callback .* failed") Base.set_active_project(nothing) @test watcher_counter[] == 1 +pop!(Base.active_project_callbacks) @test load_path() == [joinpath(@__DIR__, "project", "Project.toml")] @@ -731,14 +732,14 @@ end append!(empty!(LOAD_PATH), saved_load_path) append!(empty!(DEPOT_PATH), saved_depot_path) -for _ = 1:2 pop!(Base.active_project_callbacks) end +pop!(Base.active_project_callbacks) Base.set_active_project(saved_active_project) @test watcher_counter[] == 3 # issue #28190 -module Foo; import Libdl; end -import .Foo.Libdl; import Libdl -@test Foo.Libdl === Libdl +module Foo28190; import Libdl; end +import .Foo28190.Libdl; import Libdl +@test Foo28190.Libdl === Libdl @testset "include with mapexpr" begin let exprs = Any[] diff --git a/test/misc.jl b/test/misc.jl index 9a92d0fda0076..efc647667f4b6 100644 --- a/test/misc.jl +++ b/test/misc.jl @@ -283,6 +283,7 @@ v11801, t11801 = @timed sin(1) @test names(@__MODULE__, all = true) == names_before_timing +redirect_stdout(devnull) do # suppress time prints # Accepted @time argument formats @test @time true @test @time "message" true @@ -349,6 +350,11 @@ end after = Base.cumulative_compile_time_ns_after(); @test after >= before; +# wait for completion of these tasks before restoring stdout, to suppress their @time prints. +wait(t1); wait(t2) + +end # redirect_stdout + # interactive utilities struct ambigconvert; end # inject a problematic `convert` method to ensure it still works @@ -1065,9 +1071,16 @@ end GC.safepoint() - GC.enable_logging(true) - GC.gc() - GC.enable_logging(false) + mktemp() do tmppath, _ + open(tmppath, "w") do tmpio + redirect_stderr(tmpio) do + GC.enable_logging(true) + GC.gc() + GC.enable_logging(false) + end + end + @test occursin("GC: pause", read(open(tmppath), String)) + end end @testset "fieldtypes Module" begin diff --git a/test/secretbuffer.jl b/test/secretbuffer.jl index aea2a662766c9..df67204dd63ba 100644 --- a/test/secretbuffer.jl +++ b/test/secretbuffer.jl @@ -99,6 +99,7 @@ using Test @test position(sb) == 0 skip(sb, sb.size) @test position(sb) == sb.size + shred!(sb) end @testset "seekend" begin sb = SecretBuffer("hello") @@ -108,7 +109,6 @@ using Test end @testset "position" begin sb = SecretBuffer("Julia") - println("testing position") initial_pos = (position(sb)) seek(sb,2) mid_pos = position(sb) @@ -120,5 +120,6 @@ using Test sb1 = SecretBuffer("hello") sb2 = SecretBuffer("juliaisawesome") @test hash(sb1, UInt(5)) === hash(sb2, UInt(5)) + shred!(sb1); shred!(sb2) end end diff --git a/test/specificity.jl b/test/specificity.jl index de65c289be02a..1a5c117ce5d9d 100644 --- a/test/specificity.jl +++ b/test/specificity.jl @@ -90,7 +90,12 @@ begin @test f((1,2,3), A) == 3 @test f((1,2), A) == 2 @test f((), reshape([1])) == 1 + + oldstderr = stderr + newstderr = redirect_stderr() # redirect stderr to avoid method definition overwrite warning f(dims::NTuple{N,Int}, A::AbstractArray{T,N}) where {T,N} = 4 + redirect_stderr(oldstderr) + @test f((1,2), A) == 4 @test f((1,2,3), A) == 3 end diff --git a/test/syntax.jl b/test/syntax.jl index ff65cb235d92c..2f95b9505d056 100644 --- a/test/syntax.jl +++ b/test/syntax.jl @@ -2972,15 +2972,15 @@ end end @testset "slurping into function def" begin - x, f()... = [1, 2, 3] + x, f1()... = [1, 2, 3] @test x == 1 - @test f() == [2, 3] + @test f1() == [2, 3] # test that call to `Base.rest` is outside the definition of `f` - @test f() === f() + @test f1() === f1() - x, f()... = 1, 2, 3 + x, f2()... = 1, 2, 3 @test x == 1 - @test f() == (2, 3) + @test f2() == (2, 3) end @testset "long function bodies" begin From 901ad02eb0239cf5ba7d46ea0f386b4c512d8240 Mon Sep 17 00:00:00 2001 From: Gerhard Aigner Date: Fri, 25 Feb 2022 10:37:43 +0100 Subject: [PATCH 26/46] Indicate defaults in comandline help (#44223) Co-authored-by: Gerhard Aigner Co-authored-by: Jameson Nash (cherry picked from commit c6b5fa276b95a50280b9846243bd1f30e74d2371) --- doc/man/julia.1 | 151 +++++++++++++++---------- doc/src/manual/command-line-options.md | 51 +++++---- src/jloptions.c | 128 +++++++++++---------- test/cmdlineargs.jl | 2 +- 4 files changed, 192 insertions(+), 140 deletions(-) diff --git a/doc/man/julia.1 b/doc/man/julia.1 index 0b008619014e1..0cd5580df5556 100644 --- a/doc/man/julia.1 +++ b/doc/man/julia.1 @@ -21,16 +21,18 @@ .\" - diagnostics .\" - notes -.TH JULIA 1 2013-12-10 Julia "Julia Programmers' Reference Guide" +.TH JULIA 1 2022-02-17 JULIA .\" from the front page of https://julialang.org/ .SH NAME julia - a high-level, high-performance dynamic programming language for technical computing .SH SYNOPSIS -julia [option] [program] [args..] +\fBjulia\fR [OPTIONS...] \fB--\fR [PROGRAMMFILE] [ARGS...] + +If a Julia source file is given as a \fIPROGRAMFILE\fP (optionally followed by +arguments in \fIARGS\fP) Julia will execute the program and exit. -.\" Taken almost verbatim from the front page of https://julialang.org/ .SH DESCRIPTION Julia is a high-level, high-performance dynamic programming language for technical computing, with syntax that is familiar to users @@ -49,10 +51,6 @@ For a more in-depth discussion of the rationale and advantages of Julia over other systems, please see the online manual: https://docs.julialang.org -If a Julia source file is given as a \fIprogram\fP (optionally followed by - arguments in \fIargs\fP) Julia will execute the program and exit. - -.\" This section was taken nearly verbatim from the output of `julia --help` .SH "COMMAND-LINE OPTIONS" .TP @@ -63,6 +61,10 @@ Display version information -h, --help Print help message +.TP +--help-hidden +Print uncommon options not shown by `-h` + .TP --project[=/@.] Set as the home project/environment. The default @. option will search @@ -73,22 +75,27 @@ found. -J, --sysimage Start up with the given system image file -.TP ---sysimage-native-code={yes|no} -Use precompiled code from system image if available - .TP -H, --home Set location of julia executable .TP ---startup-file={yes|no} -Load ~/.julia/config/startup.jl +--startup-file={yes*|no} +Load `JULIA_DEPOT_PATH/config/startup.jl`; if `JULIA_DEPOT_PATH` +environment variable is unset, load `~/.julia/config/startup.jl` .TP ---handle-signals={yes|no} +--handle-signals={yes*|no} Enable or disable Julia's default signal handlers +.TP +--sysimage-native-code={yes*|no} +Use native code from system image if available + +.TP +--compiled-modules={yes*|no} +Enable or disable incremental precompilation of modules + .TP -e, --eval Evaluate @@ -106,8 +113,9 @@ Load immediately on all processors Enable n threads .TP --p, --procs -Run n local processes +-p, --procs {N|auto} +Integer value N launches N additional local worker processes `auto` launches as many workers +as the number of local CPU threads (logical cores) .TP --machine-file @@ -115,68 +123,86 @@ Run processes on hosts listed in .TP -i -Interactive mode; REPL runs and isinteractive() is true +Interactive mode; REPL runs and `isinteractive()` is true + +.TP +-q, --quiet +Quiet startup: no banner, suppress REPL warnings .TP ---banner={yes|no|auto} +--banner={yes|no|auto*} Enable or disable startup banner .TP ---color={yes|no|auto} +--color={yes|no|auto*} Enable or disable color text .TP ---history-file={yes|no} +--history-file={yes*|no} Load or save history .TP ---compile={yes|no|all|min} -Enable or disable compiler, or request exhaustive or minimal compilation +--depwarn={yes|no*|error} +Enable or disable syntax and method deprecation warnings (`error` turns warnings into errors) .TP --C, --cpu-target= -Limit usage of cpu features up to +--warn-overwrite={yes|no*} +Enable or disable method overwrite warnings .TP --O, --optimize -Run time-intensive code optimizations +--warn-scope={yes*|no} +Enable or disable warning for ambiguous top-level scope .TP --O , --optimize= -Set the optimization level to +-C, --cpu-target= +Limit usage of CPU features up to ; set to `help` to see the available options .TP ---min-optlevel= -Set the minimum optimization level to , overriding per-module settings +-O, --optimize={0,1,2*,3} +Set the optimization level (level 3 if `-O` is used without a level) .TP --g -Enable generation of full debug info +--min-optlevel={0*,1,2,3} +Set a lower bound on the optimization level .TP --g -Set the level of debug info generation to +-g {0,1*,2} +Set the level of debug info generation (level 2 if `-g` is used without a level) .TP ---inline={yes|no} -Control whether inlining is permitted (overrides functions declared as @inline) +--inline={yes*|no} +Control whether inlining is permitted, including overriding @inline declarations .TP ---check-bounds={yes|no|auto} +--check-bounds={yes|no|auto*} Emit bounds checks always, never, or respect @inbounds declarations .TP --math-mode={ieee|user} -Always use IEEE semantics for math (ignoring declarations), -or adhere to declarations in source code +Disallow or enable unsafe floating point optimizations (overrides @fastmath declaration) .TP ---depwarn={yes|no|error} -Enable or disable syntax and method deprecation warnings ('error' turns warnings into errors) +--code-coverage[={none*|user|all}] +Count executions of source lines (omitting setting is equivalent to `user`) .TP ---warn-overwrite={yes|no} -Enable or disable method overwrite warnings + --code-coverage=tracefile.info + Append coverage information to the LCOV tracefile (filename supports format tokens) + +.TP +--track-allocation[={none*|user|all}] +Count bytes allocated by each source line (omitting setting is equivalent to `user`) + +.TP +--bug-report=KIND +Launch a bug report session. It can be used to start a REPL, run a script, or evaluate +expressions. It first tries to use BugReporting.jl installed in current environment and +fallbacks to the latest compatible BugReporting.jl if not. For more information, see +--bug-report=help. + +.TP +--compile={yes*|no|all|min} +Enable or disable JIT compiler, or request exhaustive or minimal compilation .TP --output-o @@ -186,36 +212,45 @@ Generate an object file (including system image data) --output-ji Generate a system image data file (.ji) +.TP +--strip-metadata +Remove docstrings and source location info from system image + +.TP +--strip-ir +Remove IR (intermediate representation) of compiled functions + +.TP +--output-unopt-bc +Generate unoptimized LLVM bitcode (.bc) + .TP --output-bc Generate LLVM bitcode (.bc) .TP ---output-incremental={yes|no} -Generate an incremental output file (rather than complete) +--output-asm +Generate an assembly file (.s) .TP ---code-coverage={none|user|all}, --code-coverage -Count executions of source lines (omitting setting is equivalent to 'user') +--output-incremental={yes|no*} +Generate an incremental output file (rather than complete) .TP ---track-allocation={none|user|all}, --track-allocation -Count bytes allocated by each source line +--trace-compile={stderr,name} +Print precompile statements for methods compiled during execution or save to a path -.SH FILES -.I ~/.julia/config/startup.jl -.RS -Per user startup file. -.RE +.TP +-image-codegen +Force generate code in imaging mode -.I /etc/julia/startup.jl -.RS -System-wide startup file. -.RE +.SH FILES AND ENVIRONMENT +See https://docs.julialang.org/en/v1/manual/environment-variables/ .SH BUGS Please report any bugs using the GitHub issue tracker: https://github.com/julialang/julia/issues?state=open + .SH AUTHORS Contributors: https://github.com/JuliaLang/julia/graphs/contributors diff --git a/doc/src/manual/command-line-options.md b/doc/src/manual/command-line-options.md index f3ad39a6aed16..f171386604708 100644 --- a/doc/src/manual/command-line-options.md +++ b/doc/src/manual/command-line-options.md @@ -72,20 +72,20 @@ There are various ways to run Julia code and provide options, similar to those a julia [switches] -- [programfile] [args...] ``` -The following is a complete list of command-line switches available when launching julia, e.g. - +The following is a complete list of command-line switches available when launching julia (a '*' marks the default value, if applicable): |Switch |Description| |:--- |:---| |`-v`, `--version` |Display version information| |`-h`, `--help` |Print command-line options (this message).| +|`--help-hidden` |Uncommon options not shown by `-h`| |`--project[={\|@.}]` |Set `` as the home project/environment. The default `@.` option will search through parent directories until a `Project.toml` or `JuliaProject.toml` file is found.| |`-J`, `--sysimage ` |Start up with the given system image file| |`-H`, `--home ` |Set location of `julia` executable| -|`--startup-file={yes\|no}` |Load `~/.julia/config/startup.jl`| -|`--handle-signals={yes\|no}` |Enable or disable Julia's default signal handlers| -|`--sysimage-native-code={yes\|no}` |Use native code from system image if available| -|`--compiled-modules={yes\|no}` |Enable or disable incremental precompilation of modules| +|`--startup-file={yes*\|no}` |Load `JULIA_DEPOT_PATH/config/startup.jl`; if `JULIA_DEPOT_PATH` environment variable is unset, load `~/.julia/config/startup.jl`| +|`--handle-signals={yes*\|no}` |Enable or disable Julia's default signal handlers| +|`--sysimage-native-code={yes*\|no}` |Use native code from system image if available| +|`--compiled-modules={yes*\|no}` |Enable or disable incremental precompilation of modules| |`-e`, `--eval ` |Evaluate ``| |`-E`, `--print ` |Evaluate `` and display the result| |`-L`, `--load ` |Load `` immediately on all processors| @@ -94,22 +94,35 @@ The following is a complete list of command-line switches available when launchi |`--machine-file ` |Run processes on hosts listed in ``| |`-i` |Interactive mode; REPL runs and `isinteractive()` is true| |`-q`, `--quiet` |Quiet startup: no banner, suppress REPL warnings| -|`--banner={yes\|no\|auto}` |Enable or disable startup banner| -|`--color={yes\|no\|auto}` |Enable or disable color text| -|`--history-file={yes\|no}` |Load or save history| -|`--depwarn={yes\|no\|error}` |Enable or disable syntax and method deprecation warnings (`error` turns warnings into errors)| -|`--warn-overwrite={yes\|no}` |Enable or disable method overwrite warnings| +|`--banner={yes\|no\|auto*}` |Enable or disable startup banner| +|`--color={yes\|no\|auto*}` |Enable or disable color text| +|`--history-file={yes*\|no}` |Load or save history| +|`--depwarn={yes\|no*\|error}` |Enable or disable syntax and method deprecation warnings (`error` turns warnings into errors)| +|`--warn-overwrite={yes\|no*}` |Enable or disable method overwrite warnings| +|`--warn-scope={yes*\|no}` |Enable or disable warning for ambiguous top-level scope| |`-C`, `--cpu-target ` |Limit usage of CPU features up to ``; set to `help` to see the available options| -|`-O`, `--optimize={0,1,2,3}` |Set the optimization level (default level is 2 if unspecified or 3 if used without a level)| -|`--min-optlevel={0,1,2,3}` |Set the lower bound on per-module optimization (default is 0)| -|`-g`, `-g ` |Enable or set the level of debug info generation (default level is 1 if unspecified or 2 if used without a level)| +|`-O`, `--optimize={0,1,2*,3}` |Set the optimization level (level is 3 if `-O` is used without a level)| +|`--min-optlevel={0*,1,2,3}` |Set the lower bound on per-module optimization| +|`-g {0,1*,2}` |Set the level of debug info generation (level is 2 if `-g` is used without a level)| |`--inline={yes\|no}` |Control whether inlining is permitted, including overriding `@inline` declarations| -|`--check-bounds={yes\|no\|auto}` |Emit bounds checks always, never, or respect `@inbounds` declarations| +|`--check-bounds={yes\|no\|auto*}` |Emit bounds checks always, never, or respect `@inbounds` declarations| |`--math-mode={ieee,fast}` |Disallow or enable unsafe floating point optimizations (overrides `@fastmath` declaration)| -|`--code-coverage={none\|user\|all}` |Count executions of source lines| -|`--code-coverage` |equivalent to `--code-coverage=user`| -|`--track-allocation={none\|user\|all}` |Count bytes allocated by each source line| -|`--track-allocation` |equivalent to `--track-allocation=user`| +|`--code-coverage[={none*\|user\|all}]` |Count executions of source lines (omitting setting is equivalent to `user`)| +|`--code-coverage=tracefile.info` |Append coverage information to the LCOV tracefile (filename supports format tokens).| +|`--track-allocation[={none*\|user\|all}]` |Count bytes allocated by each source line (omitting setting is equivalent to "user")| +|`--bug-report=KIND` |Launch a bug report session. It can be used to start a REPL, run a script, or evaluate expressions. It first tries to use BugReporting.jl installed in current environment and fallbacks to the latest compatible BugReporting.jl if not. For more nformation, see `--bug-report=help`.| +|`--compile={yes*\|no\|all\|min}` |Enable or disable JIT compiler, or request exhaustive or minimal compilation| +|`--output-o ` |Generate an object file (including system image data)| +|`--output-ji ` |Generate a system image data file (.ji)| +|`--strip-metadata` |Remove docstrings and source location info from system image| +|`--strip-ir` |Remove IR (intermediate representation) of compiled functions| +|`--output-unopt-bc ` |Generate unoptimized LLVM bitcode (.bc)| +|`--output-bc ` |Generate LLVM bitcode (.bc)| +|`--output-asm ` |Generate an assembly file (.s)| +|`--output-incremental={yes\|no*}` |Generate an incremental output file (rather than complete)| +|`--trace-compile={stderr,name}` |Print precompile statements for methods compiled during execution or save to a path| +|`--image-codegen` |Force generate code in imaging mode| + !!! compat "Julia 1.1" In Julia 1.0, the default `--project=@.` option did not search up from the root diff --git a/src/jloptions.c b/src/jloptions.c index b85e8f7bfe386..1a572d4e25fd9 100644 --- a/src/jloptions.c +++ b/src/jloptions.c @@ -74,7 +74,7 @@ JL_DLLEXPORT void jl_init_options(void) NULL, // output-o NULL, // output-asm NULL, // output-ji - NULL, // output-code_coverage + NULL, // output-code_coverage 0, // incremental 0, // image_file_specified JL_OPTIONS_WARN_SCOPE_ON, // ambiguous scope warning @@ -86,97 +86,101 @@ JL_DLLEXPORT void jl_init_options(void) jl_options_initialized = 1; } -static const char usage[] = "julia [switches] -- [programfile] [args...]\n"; +static const char usage[] = "\n julia [switches] -- [programfile] [args...]\n\n"; static const char opts[] = - " -v, --version Display version information\n" - " -h, --help Print this message (--help-hidden for more)\n" - " --help-hidden Uncommon options not shown by `-h`\n\n" + "Switches (a '*' marks the default value, if applicable):\n\n" + " -v, --version Display version information\n" + " -h, --help Print this message (--help-hidden for more)\n" + " --help-hidden Uncommon options not shown by `-h`\n\n" // startup options - " --project[={|@.}] Set as the home project/environment\n" - " -J, --sysimage Start up with the given system image file\n" - " -H, --home Set location of `julia` executable\n" - " --startup-file={yes|no} Load `~/.julia/config/startup.jl`\n" - " --handle-signals={yes|no} Enable or disable Julia's default signal handlers\n" - " --sysimage-native-code={yes|no}\n" - " Use native code from system image if available\n" - " --compiled-modules={yes|no}\n" - " Enable or disable incremental precompilation of modules\n\n" + " --project[={|@.}] Set as the home project/environment\n" + " -J, --sysimage Start up with the given system image file\n" + " -H, --home Set location of `julia` executable\n" + " --startup-file={yes*|no} Load `JULIA_DEPOT_PATH/config/startup.jl`; if `JULIA_DEPOT_PATH`\n" + " environment variable is unset, load `~/.julia/config/startup.jl`\n" + " --handle-signals={yes*|no} Enable or disable Julia's default signal handlers\n" + " --sysimage-native-code={yes*|no}\n" + " Use native code from system image if available\n" + " --compiled-modules={yes*|no}\n" + " Enable or disable incremental precompilation of modules\n\n" // actions - " -e, --eval Evaluate \n" - " -E, --print Evaluate and display the result\n" - " -L, --load Load immediately on all processors\n\n" + " -e, --eval Evaluate \n" + " -E, --print Evaluate and display the result\n" + " -L, --load Load immediately on all processors\n\n" // parallel options - " -t, --threads {N|auto} Enable N threads; \"auto\" currently sets N to the number of local\n" - " CPU threads but this might change in the future\n" - " -p, --procs {N|auto} Integer value N launches N additional local worker processes\n" - " \"auto\" launches as many workers as the number of local CPU threads (logical cores)\n" - " --machine-file Run processes on hosts listed in \n\n" + " -t, --threads {N|auto} Enable N threads; \"auto\" currently sets N to the number of local\n" + " CPU threads but this might change in the future\n" + " -p, --procs {N|auto} Integer value N launches N additional local worker processes\n" + " \"auto\" launches as many workers as the number of local CPU threads (logical cores)\n" + " --machine-file Run processes on hosts listed in \n\n" // interactive options - " -i Interactive mode; REPL runs and isinteractive() is true\n" - " -q, --quiet Quiet startup: no banner, suppress REPL warnings\n" - " --banner={yes|no|auto} Enable or disable startup banner\n" - " --color={yes|no|auto} Enable or disable color text\n" - " --history-file={yes|no} Load or save history\n\n" + " -i Interactive mode; REPL runs and `isinteractive()` is true\n" + " -q, --quiet Quiet startup: no banner, suppress REPL warnings\n" + " --banner={yes|no|auto*} Enable or disable startup banner\n" + " --color={yes|no|auto*} Enable or disable color text\n" + " --history-file={yes*|no} Load or save history\n\n" // error and warning options - " --depwarn={yes|no|error} Enable or disable syntax and method deprecation warnings (\"error\" turns warnings into errors)\n" - " --warn-overwrite={yes|no} Enable or disable method overwrite warnings\n" - " --warn-scope={yes|no} Enable or disable warning for ambiguous top-level scope\n\n" + " --depwarn={yes|no*|error} Enable or disable syntax and method deprecation warnings (`error` turns warnings into errors)\n" + " --warn-overwrite={yes|no*} Enable or disable method overwrite warnings\n" + " --warn-scope={yes*|no} Enable or disable warning for ambiguous top-level scope\n\n" // code generation options - " -C, --cpu-target Limit usage of CPU features up to ; set to \"help\" to see the available options\n" - " -O, --optimize={0,1,2,3} Set the optimization level (default level is 2 if unspecified or 3 if used without a level)\n" - " --min-optlevel={0,1,2,3} Set a lower bound on the optimization level (default is 0)\n" - " -g, -g Enable or set the level of debug info generation" + " -C, --cpu-target Limit usage of CPU features up to ; set to `help` to see the available options\n" + " -O, --optimize={0,1,2*,3} Set the optimization level (level 3 if `-O` is used without a level)\n" + " --min-optlevel={0*,1,2,3} Set a lower bound on the optimization level\n" #ifdef JL_DEBUG_BUILD - " (default level for julia-debug is 2 if unspecified or if used without a level)\n" + " -g [{0,1,2*}] Set the level of debug info generation in the julia-debug build\n" #else - " (default level is 1 if unspecified or 2 if used without a level)\n" + " -g [{0,1*,2}] Set the level of debug info generation (level 2 if `-g` is used without a level)\n" #endif - " --inline={yes|no} Control whether inlining is permitted, including overriding @inline declarations\n" - " --check-bounds={yes|no|auto}\n" - " Emit bounds checks always, never, or respect @inbounds declarations\n" + " --inline={yes*|no} Control whether inlining is permitted, including overriding @inline declarations\n" + " --check-bounds={yes|no|auto*}\n" + " Emit bounds checks always, never, or respect @inbounds declarations\n" #ifdef USE_POLLY - " --polly={yes|no} Enable or disable the polyhedral optimizer Polly (overrides @polly declaration)\n" + " --polly={yes*|no} Enable or disable the polyhedral optimizer Polly (overrides @polly declaration)\n" #endif - " --math-mode={ieee,fast} Disallow or enable unsafe floating point optimizations (overrides @fastmath declaration)\n\n" + " --math-mode={ieee,fast} Disallow or enable unsafe floating point optimizations (overrides @fastmath declaration)\n\n" // instrumentation options - " --code-coverage={none|user|all}, --code-coverage\n" - " Count executions of source lines (omitting setting is equivalent to \"user\")\n" + " --code-coverage[={none*|user|all}]\n" + " Count executions of source lines (omitting setting is equivalent to `user`)\n" " --code-coverage=tracefile.info\n" - " Append coverage information to the LCOV tracefile (filename supports format tokens).\n" + " Append coverage information to the LCOV tracefile (filename supports format tokens)\n" // TODO: These TOKENS are defined in `runtime_ccall.cpp`. A more verbose `--help` should include that list here. - " --track-allocation={none|user|all}, --track-allocation\n" - " Count bytes allocated by each source line (omitting setting is equivalent to \"user\")\n" - " --bug-report=KIND Launch a bug report session. It can be used to start a REPL, run a script, or evaluate\n" - " expressions. It first tries to use BugReporting.jl installed in current environment and\n" - " fallbacks to the latest compatible BugReporting.jl if not. For more information, see\n" - " --bug-report=help.\n\n" + " --track-allocation[={none*|user|all}]\n" + " Count bytes allocated by each source line (omitting setting is equivalent to `user`)\n" + " --bug-report=KIND Launch a bug report session. It can be used to start a REPL, run a script, or evaluate\n" + " expressions. It first tries to use BugReporting.jl installed in current environment and\n" + " fallbacks to the latest compatible BugReporting.jl if not. For more information, see\n" + " --bug-report=help.\n\n" ; static const char opts_hidden[] = + "Switches (a '*' marks the default value, if applicable):\n\n" // code generation options - " --compile={yes|no|all|min}Enable or disable JIT compiler, or request exhaustive or minimal compilation\n" + " --compile={yes*|no|all|min}\n" + " Enable or disable JIT compiler, or request exhaustive or minimal compilation\n\n" // compiler output options - " --output-o name Generate an object file (including system image data)\n" - " --output-ji name Generate a system image data file (.ji)\n" - " --strip-metadata Remove docstrings and source location info from system image\n" - " --strip-ir Remove IR (intermediate representation) of compiled functions\n" + " --output-o Generate an object file (including system image data)\n" + " --output-ji Generate a system image data file (.ji)\n" + " --strip-metadata Remove docstrings and source location info from system image\n" + " --strip-ir Remove IR (intermediate representation) of compiled functions\n\n" // compiler debugging (see the devdocs for tips on using these options) - " --output-unopt-bc name Generate unoptimized LLVM bitcode (.bc)\n" - " --output-bc name Generate LLVM bitcode (.bc)\n" - " --output-asm name Generate an assembly file (.s)\n" - " --output-incremental=no Generate an incremental output file (rather than complete)\n" + " --output-unopt-bc Generate unoptimized LLVM bitcode (.bc)\n" + " --output-bc Generate LLVM bitcode (.bc)\n" + " --output-asm Generate an assembly file (.s)\n" + " --output-incremental={yes|no*}\n" + " Generate an incremental output file (rather than complete)\n" " --trace-compile={stderr,name}\n" - " Print precompile statements for methods compiled during execution or save to a path\n\n" - " --image-codegen Force generate code in imaging mode\n" + " Print precompile statements for methods compiled during execution or save to a path\n" + " --image-codegen Force generate code in imaging mode\n" ; JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp) @@ -237,7 +241,7 @@ JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp) { "bug-report", required_argument, 0, opt_bug_report }, { "sysimage", required_argument, 0, 'J' }, { "sysimage-native-code", required_argument, 0, opt_sysimage_native_code }, - { "compiled-modules", required_argument, 0, opt_compiled_modules }, + { "compiled-modules",required_argument, 0, opt_compiled_modules }, { "cpu-target", required_argument, 0, 'C' }, { "procs", required_argument, 0, 'p' }, { "threads", required_argument, 0, 't' }, diff --git a/test/cmdlineargs.jl b/test/cmdlineargs.jl index 0a03e60f6dd03..8f11f6a6c7a44 100644 --- a/test/cmdlineargs.jl +++ b/test/cmdlineargs.jl @@ -123,7 +123,7 @@ let exename = `$(Base.julia_cmd()) --startup-file=no --color=no` @test read(`$exename -v`, String) == read(`$exename --version`, String) # --help - let header = "julia [switches] -- [programfile] [args...]" + let header = "\n julia [switches] -- [programfile] [args...]" @test startswith(read(`$exename -h`, String), header) @test startswith(read(`$exename --help`, String), header) end From bedccaf7a25fe4624f2d88746cf35668c175f337 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Thu, 3 Mar 2022 08:16:02 -0500 Subject: [PATCH 27/46] Add option for codecov and allocation tracking to be restricted by path (#44359) (cherry picked from commit 166b829a208a0aaa3c1f27d6e2134e409b2b6806) --- base/options.jl | 1 + base/util.jl | 4 +++ doc/man/julia.1 | 10 +++++++ src/codegen.cpp | 37 +++++++++++++++--------- src/init.c | 2 ++ src/jloptions.c | 18 ++++++++++++ src/jloptions.h | 1 + src/julia.h | 1 + test/cmdlineargs.jl | 33 +++++++++++++++++++++ test/testhelpers/coverage_file.info.bad2 | 20 +++++++++++++ 10 files changed, 113 insertions(+), 14 deletions(-) create mode 100644 test/testhelpers/coverage_file.info.bad2 diff --git a/base/options.jl b/base/options.jl index 2af8337673b93..52bfb1237a858 100644 --- a/base/options.jl +++ b/base/options.jl @@ -20,6 +20,7 @@ struct JLOptions compile_enabled::Int8 code_coverage::Int8 malloc_log::Int8 + tracked_path::Ptr{UInt8} opt_level::Int8 opt_level_min::Int8 debug_level::Int8 diff --git a/base/util.jl b/base/util.jl index 935f357367a8e..df9e29790deb6 100644 --- a/base/util.jl +++ b/base/util.jl @@ -196,6 +196,8 @@ function julia_cmd(julia=joinpath(Sys.BINDIR, julia_exename())) push!(addflags, "--code-coverage=user") elseif opts.code_coverage == 2 push!(addflags, "--code-coverage=all") + elseif opts.code_coverage == 3 + push!(addflags, "--code-coverage=@$(unsafe_string(opts.tracked_path))") end isempty(coverage_file) || push!(addflags, "--code-coverage=$coverage_file") end @@ -204,6 +206,8 @@ function julia_cmd(julia=joinpath(Sys.BINDIR, julia_exename())) push!(addflags, "--track-allocation=user") elseif opts.malloc_log == 2 push!(addflags, "--track-allocation=all") + elseif opts.malloc_log == 3 + push!(addflags, "--track-allocation=@$(unsafe_string(opts.tracked_path))") end if opts.color == 1 push!(addflags, "--color=yes") diff --git a/doc/man/julia.1 b/doc/man/julia.1 index 0cd5580df5556..249c8e0bd214e 100644 --- a/doc/man/julia.1 +++ b/doc/man/julia.1 @@ -185,6 +185,11 @@ Disallow or enable unsafe floating point optimizations (overrides @fastmath decl --code-coverage[={none*|user|all}] Count executions of source lines (omitting setting is equivalent to `user`) +.TP +--code-coverage=@ +Count executions of source lines in a file or files under a given directory. A `@` must +be placed before the path to indicate this option. A `@` with no path will track the current directory. + .TP --code-coverage=tracefile.info Append coverage information to the LCOV tracefile (filename supports format tokens) @@ -193,6 +198,11 @@ Count executions of source lines (omitting setting is equivalent to `user`) --track-allocation[={none*|user|all}] Count bytes allocated by each source line (omitting setting is equivalent to `user`) +.TP +--track-allocation=@ +Count bytes allocated by each source line in a file or files under a given directory. A `@` +must be placed before the path to indicate this option. A `@` with no path will track the current directory. + .TP --bug-report=KIND Launch a bug report session. It can be used to start a REPL, run a script, or evaluate diff --git a/src/codegen.cpp b/src/codegen.cpp index c9e7b2280777e..89107f99413dc 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -6956,15 +6956,20 @@ static std::pair, jl_llvm_functions_t> return (!jl_is_submodule(mod, jl_base_module) && !jl_is_submodule(mod, jl_core_module)); }; + auto in_tracked_path = [] (StringRef file) { + return jl_options.tracked_path != NULL && file.startswith(jl_options.tracked_path); + }; bool mod_is_user_mod = in_user_mod(ctx.module); + bool mod_is_tracked = in_tracked_path(ctx.file); struct DebugLineTable { DebugLoc loc; StringRef file; ssize_t line; bool is_user_code; + bool is_tracked; // falls within an explicitly set file or directory unsigned inlined_at; bool operator ==(const DebugLineTable &other) const { - return other.loc == loc && other.file == file && other.line == line && other.is_user_code == is_user_code && other.inlined_at == inlined_at; + return other.loc == loc && other.file == file && other.line == line && other.is_user_code == is_user_code && other.is_tracked == is_tracked && other.inlined_at == inlined_at; } }; std::vector linetable; @@ -6977,6 +6982,7 @@ static std::pair, jl_llvm_functions_t> topinfo.file = ctx.file; topinfo.line = toplineno; topinfo.is_user_code = mod_is_user_mod; + topinfo.is_tracked = mod_is_tracked; topinfo.inlined_at = 0; topinfo.loc = topdebugloc; for (size_t i = 0; i < nlocs; i++) { @@ -6990,13 +6996,14 @@ static std::pair, jl_llvm_functions_t> info.line = jl_unbox_long(jl_fieldref(locinfo, 3)); info.inlined_at = jl_unbox_long(jl_fieldref(locinfo, 4)); assert(info.inlined_at <= i); + info.file = jl_symbol_name(filesym); + if (info.file.empty()) + info.file = ""; if (module == ctx.module) info.is_user_code = mod_is_user_mod; else info.is_user_code = in_user_mod(module); - info.file = jl_symbol_name(filesym); - if (info.file.empty()) - info.file = ""; + info.is_tracked = in_tracked_path(info.file); if (ctx.debug_enabled) { StringRef fname; if (jl_is_method_instance(method)) @@ -7110,13 +7117,15 @@ static std::pair, jl_llvm_functions_t> cursor = -1; }; - auto do_coverage = [&] (bool in_user_code) { + auto do_coverage = [&] (bool in_user_code, bool is_tracked) { return (coverage_mode == JL_LOG_ALL || - (coverage_mode == JL_LOG_USER && in_user_code)); + (in_user_code && coverage_mode == JL_LOG_USER) || + (is_tracked && coverage_mode == JL_LOG_PATH)); }; - auto do_malloc_log = [&] (bool in_user_code) { + auto do_malloc_log = [&] (bool in_user_code, bool is_tracked) { return (malloc_log_mode == JL_LOG_ALL || - (malloc_log_mode == JL_LOG_USER && in_user_code)); + (in_user_code && malloc_log_mode == JL_LOG_USER) || + (is_tracked && malloc_log_mode == JL_LOG_PATH)); }; std::vector current_lineinfo, new_lineinfo; auto coverageVisitStmt = [&] (size_t dbg) { @@ -7135,15 +7144,15 @@ static std::pair, jl_llvm_functions_t> if (newdbg != current_lineinfo[dbg]) { current_lineinfo[dbg] = newdbg; const auto &info = linetable.at(newdbg); - if (do_coverage(info.is_user_code)) + if (do_coverage(info.is_user_code, info.is_tracked)) coverageVisitLine(ctx, info.file, info.line); } } new_lineinfo.clear(); }; auto mallocVisitStmt = [&] (unsigned dbg, Value *sync) { - if (!do_malloc_log(mod_is_user_mod) || dbg == 0) { - if (do_malloc_log(true) && sync) + if (!do_malloc_log(mod_is_user_mod, mod_is_tracked) || dbg == 0) { + if (do_malloc_log(true, mod_is_tracked) && sync) ctx.builder.CreateCall(prepare_call(sync_gc_total_bytes_func), {sync}); return; } @@ -7154,7 +7163,7 @@ static std::pair, jl_llvm_functions_t> if (coverage_mode != JL_LOG_NONE) { // record all lines that could be covered for (const auto &info : linetable) - if (do_coverage(info.is_user_code)) + if (do_coverage(info.is_user_code, info.is_tracked)) jl_coverage_alloc_line(info.file, info.line); } @@ -7209,7 +7218,7 @@ static std::pair, jl_llvm_functions_t> } Value *sync_bytes = nullptr; - if (do_malloc_log(true)) + if (do_malloc_log(true, mod_is_tracked)) sync_bytes = ctx.builder.CreateCall(prepare_call(diff_gc_total_bytes_func), {}); { // coverage for the function definition line number const auto &topinfo = linetable.at(0); @@ -7217,7 +7226,7 @@ static std::pair, jl_llvm_functions_t> if (topinfo == linetable.at(1)) current_lineinfo.push_back(1); } - if (do_coverage(topinfo.is_user_code)) + if (do_coverage(topinfo.is_user_code, topinfo.is_tracked)) coverageVisitLine(ctx, topinfo.file, topinfo.line); } diff --git a/src/init.c b/src/init.c index 724261704836e..6bebffdcf326c 100644 --- a/src/init.c +++ b/src/init.c @@ -583,6 +583,8 @@ static void jl_resolve_sysimg_location(JL_IMAGE_SEARCH rel) jl_options.machine_file = abspath(jl_options.machine_file, 0); if (jl_options.output_code_coverage) jl_options.output_code_coverage = absformat(jl_options.output_code_coverage); + if (jl_options.tracked_path) + jl_options.tracked_path = absformat(jl_options.tracked_path); const char **cmdp = jl_options.cmds; if (cmdp) { diff --git a/src/jloptions.c b/src/jloptions.c index 1a572d4e25fd9..978da79c1e95d 100644 --- a/src/jloptions.c +++ b/src/jloptions.c @@ -49,6 +49,7 @@ JL_DLLEXPORT void jl_init_options(void) JL_OPTIONS_COMPILE_DEFAULT, // compile_enabled 0, // code_coverage 0, // malloc_log + NULL, // tracked_path 2, // opt_level 0, // opt_level_min #ifdef JL_DEBUG_BUILD @@ -149,11 +150,20 @@ static const char opts[] = // instrumentation options " --code-coverage[={none*|user|all}]\n" " Count executions of source lines (omitting setting is equivalent to `user`)\n" + " --code-coverage=@\n" + " Count executions but only in files that fall under the given file path/directory.\n" + " The `@` prefix is required to select this option. A `@` with no path will track the\n" + " current directory.\n" + " --code-coverage=tracefile.info\n" " Append coverage information to the LCOV tracefile (filename supports format tokens)\n" // TODO: These TOKENS are defined in `runtime_ccall.cpp`. A more verbose `--help` should include that list here. " --track-allocation[={none*|user|all}]\n" " Count bytes allocated by each source line (omitting setting is equivalent to `user`)\n" + " --track-allocation=@\n" + " Count bytes but only in files that fall under the given file path/directory.\n" + " The `@` prefix is required to select this option. A `@` with no path will track the\n" + " current directory.\n" " --bug-report=KIND Launch a bug report session. It can be used to start a REPL, run a script, or evaluate\n" " expressions. It first tries to use BugReporting.jl installed in current environment and\n" " fallbacks to the latest compatible BugReporting.jl if not. For more information, see\n" @@ -515,6 +525,10 @@ JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp) codecov = JL_LOG_ALL; jl_options.output_code_coverage = optarg; } + else if (!strncmp(optarg, "@", 1)) { + codecov = JL_LOG_PATH; + jl_options.tracked_path = optarg + 1; // skip `@` + } else jl_errorf("julia: invalid argument to --code-coverage (%s)", optarg); break; @@ -531,6 +545,10 @@ JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp) malloclog = JL_LOG_ALL; else if (!strcmp(optarg,"none")) malloclog = JL_LOG_NONE; + else if (!strncmp(optarg, "@", 1)) { + malloclog = JL_LOG_PATH; + jl_options.tracked_path = optarg + 1; // skip `@` + } else jl_errorf("julia: invalid argument to --track-allocation (%s)", optarg); break; diff --git a/src/jloptions.h b/src/jloptions.h index 0f53bc0f8a4de..2425b2bb680c2 100644 --- a/src/jloptions.h +++ b/src/jloptions.h @@ -24,6 +24,7 @@ typedef struct { int8_t compile_enabled; int8_t code_coverage; int8_t malloc_log; + const char *tracked_path; int8_t opt_level; int8_t opt_level_min; int8_t debug_level; diff --git a/src/julia.h b/src/julia.h index 2d51de2f3ed9b..5e22c262fb47d 100644 --- a/src/julia.h +++ b/src/julia.h @@ -2077,6 +2077,7 @@ JL_DLLEXPORT int jl_generating_output(void) JL_NOTSAFEPOINT; #define JL_LOG_NONE 0 #define JL_LOG_USER 1 #define JL_LOG_ALL 2 +#define JL_LOG_PATH 3 #define JL_OPTIONS_CHECK_BOUNDS_DEFAULT 0 #define JL_OPTIONS_CHECK_BOUNDS_ON 1 diff --git a/test/cmdlineargs.jl b/test/cmdlineargs.jl index 8f11f6a6c7a44..43d3728dcb988 100644 --- a/test/cmdlineargs.jl +++ b/test/cmdlineargs.jl @@ -326,6 +326,39 @@ let exename = `$(Base.julia_cmd()) --startup-file=no --color=no` rm(covfile) @test occursin(expected, got) || (expected, got) @test_broken occursin(expected_good, got) + + # Ask for coverage in specific file + # TODO: Figure out why asking for a specific file/dir means some lines are under-counted + # NOTE that a different expected reference is loaded here + expected = replace(read(joinpath(helperdir, "coverage_file.info.bad2"), String), + "" => realpath(inputfile)) + tfile = realpath(inputfile) + @test readchomp(`$exename -E "(Base.JLOptions().code_coverage, unsafe_string(Base.JLOptions().tracked_path))" -L $inputfile + --code-coverage=$covfile --code-coverage=@$tfile`) == "(3, $(repr(tfile)))" + @test isfile(covfile) + got = read(covfile, String) + rm(covfile) + @test occursin(expected, got) || (expected, got) + @test_broken occursin(expected_good, got) + + # Ask for coverage in directory + tdir = dirname(realpath(inputfile)) + @test readchomp(`$exename -E "(Base.JLOptions().code_coverage, unsafe_string(Base.JLOptions().tracked_path))" -L $inputfile + --code-coverage=$covfile --code-coverage=@$tdir`) == "(3, $(repr(tdir)))" + @test isfile(covfile) + got = read(covfile, String) + rm(covfile) + @test occursin(expected, got) || (expected, got) + @test_broken occursin(expected_good, got) + + # Ask for coverage in a different directory + tdir = mktempdir() # a dir that contains no code + @test readchomp(`$exename -E "(Base.JLOptions().code_coverage, unsafe_string(Base.JLOptions().tracked_path))" -L $inputfile + --code-coverage=$covfile --code-coverage=@$tdir`) == "(3, $(repr(tdir)))" + @test isfile(covfile) + got = read(covfile, String) + @test isempty(got) + rm(covfile) end # --track-allocation diff --git a/test/testhelpers/coverage_file.info.bad2 b/test/testhelpers/coverage_file.info.bad2 new file mode 100644 index 0000000000000..a766597be4c17 --- /dev/null +++ b/test/testhelpers/coverage_file.info.bad2 @@ -0,0 +1,20 @@ +SF: +DA:3,1 +DA:4,1 +DA:5,0 +DA:7,1 +DA:8,1 +DA:9,3 +DA:10,5 +DA:11,0 +DA:12,1 +DA:14,0 +DA:17,1 +DA:18,0 +DA:19,0 +DA:20,0 +DA:22,1 +DA:1234,0 +LH:9 +LF:16 +end_of_record From c4f6c1260358ff252d980320f0c6512eea6b4a89 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Wed, 23 Feb 2022 14:08:22 +0900 Subject: [PATCH 28/46] inference: remove `CachedMethodTable` (#44240) Since we couldn't confirm any performance benefit from `CachedMethodTable` in the current infrastructure (see the benchmark results in #44240), now I'd like to propose to eliminate that entirely and save a bit of space. --- base/compiler/inferencestate.jl | 4 +-- base/compiler/methodtable.jl | 53 +++++++++------------------------ base/compiler/types.jl | 1 - 3 files changed, 16 insertions(+), 42 deletions(-) diff --git a/base/compiler/inferencestate.jl b/base/compiler/inferencestate.jl index 17539f7621c74..39c4c9a2ceb66 100644 --- a/base/compiler/inferencestate.jl +++ b/base/compiler/inferencestate.jl @@ -65,7 +65,7 @@ mutable struct InferenceState # The place to look up methods while working on this function. # In particular, we cache method lookup results for the same function to # fast path repeated queries. - method_table::CachedMethodTable{InternalMethodTable} + method_table::InternalMethodTable # The interpreter that created this inference state. Not looked at by # NativeInterpreter. But other interpreters may use this to detect cycles @@ -141,7 +141,7 @@ mutable struct InferenceState cache === :global, false, false, Effects(consistent, ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE, inbounds_taints_consistency), - CachedMethodTable(method_table(interp)), + method_table(interp), interp) result.result = frame cache !== :no && push!(get_inference_cache(interp), result) diff --git a/base/compiler/methodtable.jl b/base/compiler/methodtable.jl index 70beb259cb6a5..4086023a725f0 100644 --- a/base/compiler/methodtable.jl +++ b/base/compiler/methodtable.jl @@ -2,22 +2,6 @@ abstract type MethodTableView; end -struct MethodLookupResult - # Really Vector{Core.MethodMatch}, but it's easier to represent this as - # and work with Vector{Any} on the C side. - matches::Vector{Any} - valid_worlds::WorldRange - ambig::Bool -end -length(result::MethodLookupResult) = length(result.matches) -function iterate(result::MethodLookupResult, args...) - r = iterate(result.matches, args...) - r === nothing && return nothing - match, state = r - return (match::MethodMatch, state) -end -getindex(result::MethodLookupResult, idx::Int) = getindex(result.matches, idx)::MethodMatch - """ struct InternalMethodTable <: MethodTableView @@ -39,19 +23,21 @@ struct OverlayMethodTable <: MethodTableView mt::Core.MethodTable end -""" - struct CachedMethodTable <: MethodTableView - -Overlays another method table view with an additional local fast path cache that -can respond to repeated, identical queries faster than the original method table. -""" -struct CachedMethodTable{T} <: MethodTableView - cache::IdDict{Any, Union{Missing, MethodLookupResult}} - table::T +struct MethodLookupResult + # Really Vector{Core.MethodMatch}, but it's easier to represent this as + # and work with Vector{Any} on the C side. + matches::Vector{Any} + valid_worlds::WorldRange + ambig::Bool +end +length(result::MethodLookupResult) = length(result.matches) +function iterate(result::MethodLookupResult, args...) + r = iterate(result.matches, args...) + r === nothing && return nothing + match, state = r + return (match::MethodMatch, state) end -CachedMethodTable(table::T) where T = - CachedMethodTable{T}(IdDict{Any, Union{Missing, MethodLookupResult}}(), - table) +getindex(result::MethodLookupResult, idx::Int) = getindex(result.matches, idx)::MethodMatch """ findall(sig::Type, view::MethodTableView; limit=typemax(Int)) @@ -91,13 +77,6 @@ function findall(@nospecialize(sig::Type), table::OverlayMethodTable; limit::Int return MethodLookupResult(ms::Vector{Any}, WorldRange(_min_val[], _max_val[]), _ambig[] != 0) end -function findall(@nospecialize(sig::Type), table::CachedMethodTable; limit::Int=typemax(Int)) - box = Core.Box(sig) - return get!(table.cache, sig) do - findall(box.contents, table.table; limit=limit) - end -end - """ findsup(sig::Type, view::MethodTableView)::Union{Tuple{MethodMatch, WorldRange}, Nothing} @@ -121,10 +100,6 @@ function findsup(@nospecialize(sig::Type), table::InternalMethodTable) (result.method, WorldRange(min_valid[], max_valid[])) end -# This query is not cached -findsup(@nospecialize(sig::Type), table::CachedMethodTable) = findsup(sig, table.table) - isoverlayed(::MethodTableView) = error("unsatisfied MethodTableView interface") isoverlayed(::InternalMethodTable) = false isoverlayed(::OverlayMethodTable) = true -isoverlayed(mt::CachedMethodTable) = isoverlayed(mt.table) diff --git a/base/compiler/types.jl b/base/compiler/types.jl index 956fd7c747e80..1fd33d47f0408 100644 --- a/base/compiler/types.jl +++ b/base/compiler/types.jl @@ -263,7 +263,6 @@ struct NativeInterpreter <: AbstractInterpreter # incorrect, fail out loudly. @assert world <= get_world_counter() - return new( # Initially empty cache Vector{InferenceResult}(), From 5bd974a9da04f924d12bc8e407f817a938b9cef7 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Thu, 3 Mar 2022 10:31:35 +0900 Subject: [PATCH 29/46] `AbstractInterpreter`: remove `method_table(::AbstractInterpreter, ::InferenceState)` interface (#44389) In #44240 we removed the `CachedMethodTable` support as it turned out to be ineffective under the current compiler infrastructure. Because of this, there is no strong reason to keep a method table per `InferenceState`. This commit simply removes the `method_table(::AbstractInterpreter, ::InferenceState)` interface and should make it clearer which interface should be overloaded to implement a contextual dispatch. --- base/compiler/abstractinterpretation.jl | 14 ++++---- base/compiler/inferencestate.jl | 31 ++++++---------- base/compiler/types.jl | 7 ++++ test/choosetests.jl | 2 +- test/compiler/AbstractInterpreter.jl | 47 +++++++++++++++++++++++++ 5 files changed, 73 insertions(+), 28 deletions(-) create mode 100644 test/compiler/AbstractInterpreter.jl diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index 39cabe33ff043..53cc5fdeddf09 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -47,7 +47,7 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f), end argtypes = arginfo.argtypes - matches = find_matching_methods(argtypes, atype, method_table(interp, sv), InferenceParams(interp).MAX_UNION_SPLITTING, max_methods) + matches = find_matching_methods(argtypes, atype, method_table(interp), InferenceParams(interp).MAX_UNION_SPLITTING, max_methods) if isa(matches, FailedMethodMatch) add_remark!(interp, sv, matches.reason) tristate_merge!(sv, Effects()) @@ -637,7 +637,7 @@ end function pure_eval_eligible(interp::AbstractInterpreter, @nospecialize(f), applicable::Vector{Any}, arginfo::ArgInfo, sv::InferenceState) - return !isoverlayed(method_table(interp, sv)) && + return !isoverlayed(method_table(interp)) && f !== nothing && length(applicable) == 1 && is_method_pure(applicable[1]::MethodMatch) && @@ -674,7 +674,7 @@ end function concrete_eval_eligible(interp::AbstractInterpreter, @nospecialize(f), result::MethodCallResult, arginfo::ArgInfo, sv::InferenceState) - return !isoverlayed(method_table(interp, sv)) && + return !isoverlayed(method_table(interp)) && f !== nothing && result.edge !== nothing && is_total_or_error(result.edge_effects) && @@ -2110,14 +2110,14 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState) frame.dont_work_on_me = true # mark that this function is currently on the stack W = frame.ip states = frame.stmt_types - n = frame.nstmts + nstmts = frame.nstmts nargs = frame.nargs def = frame.linfo.def isva = isa(def, Method) && def.isva nslots = nargs - isva slottypes = frame.slottypes ssavaluetypes = frame.src.ssavaluetypes::Vector{Any} - while frame.pc´´ <= n + while frame.pc´´ <= nstmts # make progress on the active ip set local pc::Int = frame.pc´´ while true # inner loop optimizes the common case where it can run straight from pc to pc + 1 @@ -2189,7 +2189,7 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState) end end elseif isa(stmt, ReturnNode) - pc´ = n + 1 + pc´ = nstmts + 1 bestguess = frame.bestguess rt = abstract_eval_value(interp, stmt.val, changes, frame) rt = widenreturn(rt, bestguess, nslots, slottypes, changes) @@ -2310,7 +2310,7 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState) ssavaluetypes[pc] = Any end - pc´ > n && break # can't proceed with the fast-path fall-through + pc´ > nstmts && break # can't proceed with the fast-path fall-through newstate = stupdate!(states[pc´], changes) if isa(stmt, GotoNode) && frame.pc´´ < pc´ # if we are processing a goto node anyways, diff --git a/base/compiler/inferencestate.jl b/base/compiler/inferencestate.jl index 39c4c9a2ceb66..928811dd63a3b 100644 --- a/base/compiler/inferencestate.jl +++ b/base/compiler/inferencestate.jl @@ -62,11 +62,6 @@ mutable struct InferenceState # Inferred purity flags ipo_effects::Effects - # The place to look up methods while working on this function. - # In particular, we cache method lookup results for the same function to - # fast path repeated queries. - method_table::InternalMethodTable - # The interpreter that created this inference state. Not looked at by # NativeInterpreter. But other interpreters may use this to detect cycles interp::AbstractInterpreter @@ -85,9 +80,9 @@ mutable struct InferenceState src.ssavaluetypes = Any[ NOT_FOUND for i = 1:nssavalues ] stmt_info = Any[ nothing for i = 1:length(code) ] - n = length(code) - s_types = Union{Nothing, VarTable}[ nothing for i = 1:n ] - s_edges = Union{Nothing, Vector{Any}}[ nothing for i = 1:n ] + nstmts = length(code) + s_types = Union{Nothing, VarTable}[ nothing for i = 1:nstmts ] + s_edges = Union{Nothing, Vector{Any}}[ nothing for i = 1:nstmts ] # initial types nslots = length(src.slotflags) @@ -129,19 +124,17 @@ mutable struct InferenceState @assert cache === :no || cache === :local || cache === :global frame = new( params, result, linfo, - sp, slottypes, mod, 0, - IdSet{InferenceState}(), IdSet{InferenceState}(), + sp, slottypes, mod, #=currpc=#0, + #=pclimitations=#IdSet{InferenceState}(), #=limitations=#IdSet{InferenceState}(), src, get_world_counter(interp), valid_worlds, nargs, s_types, s_edges, stmt_info, - Union{}, ip, 1, n, handler_at, - ssavalue_uses, - Vector{Tuple{InferenceState,LineNum}}(), # cycle_backedges - Vector{InferenceState}(), # callers_in_cycle + #=bestguess=#Union{}, ip, #=pc´´=#1, nstmts, handler_at, ssavalue_uses, + #=cycle_backedges=#Vector{Tuple{InferenceState,LineNum}}(), + #=callers_in_cycle=#Vector{InferenceState}(), #=parent=#nothing, - cache === :global, false, false, - Effects(consistent, ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE, - inbounds_taints_consistency), - method_table(interp), + #=cached=#cache === :global, + #=inferred=#false, #=dont_work_on_me=#false, + #=ipo_effects=#Effects(consistent, ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE, inbounds_taints_consistency), interp) result.result = frame cache !== :no && push!(get_inference_cache(interp), result) @@ -267,8 +260,6 @@ function iterate(unw::InfStackUnwind, (infstate, cyclei)::Tuple{InferenceState, (infstate::InferenceState, (infstate, cyclei)) end -method_table(interp::AbstractInterpreter, sv::InferenceState) = sv.method_table - function InferenceState(result::InferenceResult, cache::Symbol, interp::AbstractInterpreter) # prepare an InferenceState object for inferring lambda src = retrieve_code_info(result.linfo) diff --git a/base/compiler/types.jl b/base/compiler/types.jl index 1fd33d47f0408..6d4a650470237 100644 --- a/base/compiler/types.jl +++ b/base/compiler/types.jl @@ -314,6 +314,13 @@ may_compress(::AbstractInterpreter) = true may_discard_trees(::AbstractInterpreter) = true verbose_stmt_info(::AbstractInterpreter) = false +""" + method_table(interp::AbstractInterpreter) -> MethodTableView + +Returns a method table this `interp` uses for method lookup. +External `AbstractInterpreter` can optionally return `OverlayMethodTable` here +to incorporate customized dispatches for the overridden methods. +""" method_table(interp::AbstractInterpreter) = InternalMethodTable(get_world_counter(interp)) """ diff --git a/test/choosetests.jl b/test/choosetests.jl index f86f665bc2217..099dfa18a71c5 100644 --- a/test/choosetests.jl +++ b/test/choosetests.jl @@ -142,7 +142,7 @@ function choosetests(choices = []) filtertests!(tests, "subarray") filtertests!(tests, "compiler", ["compiler/inference", "compiler/validation", "compiler/ssair", "compiler/irpasses", "compiler/codegen", - "compiler/inline", "compiler/contextual", + "compiler/inline", "compiler/contextual", "compiler/AbstractInterpreter", "compiler/EscapeAnalysis/local", "compiler/EscapeAnalysis/interprocedural"]) filtertests!(tests, "compiler/EscapeAnalysis", [ "compiler/EscapeAnalysis/local", "compiler/EscapeAnalysis/interprocedural"]) diff --git a/test/compiler/AbstractInterpreter.jl b/test/compiler/AbstractInterpreter.jl new file mode 100644 index 0000000000000..6ef2adf7177fa --- /dev/null +++ b/test/compiler/AbstractInterpreter.jl @@ -0,0 +1,47 @@ +# This file is a part of Julia. License is MIT: https://julialang.org/license + +const CC = Core.Compiler +import Core: MethodInstance, CodeInstance +import .CC: WorldRange, WorldView + +# define new `AbstractInterpreter` that satisfies the minimum interface requirements +# while managing its cache independently +macro newinterp(name) + cachename = gensym(string(name, "Cache")) + name = esc(name) + quote + struct $cachename + dict::IdDict{MethodInstance,CodeInstance} + end + struct $name <: CC.AbstractInterpreter + interp::CC.NativeInterpreter + cache::$cachename + $name(world = Base.get_world_counter(); + interp = CC.NativeInterpreter(world), + cache = $cachename(IdDict{MethodInstance,CodeInstance}()) + ) = new(interp, cache) + end + CC.InferenceParams(interp::$name) = CC.InferenceParams(interp.interp) + CC.OptimizationParams(interp::$name) = CC.OptimizationParams(interp.interp) + CC.get_world_counter(interp::$name) = CC.get_world_counter(interp.interp) + CC.get_inference_cache(interp::$name) = CC.get_inference_cache(interp.interp) + CC.code_cache(interp::$name) = WorldView(interp.cache, WorldRange(CC.get_world_counter(interp))) + CC.get(wvc::WorldView{<:$cachename}, mi::MethodInstance, default) = get(wvc.cache.dict, mi, default) + CC.getindex(wvc::WorldView{<:$cachename}, mi::MethodInstance) = getindex(wvc.cache.dict, mi) + CC.haskey(wvc::WorldView{<:$cachename}, mi::MethodInstance) = haskey(wvc.cache.dict, mi) + CC.setindex!(wvc::WorldView{<:$cachename}, ci::CodeInstance, mi::MethodInstance) = setindex!(wvc.cache.dict, ci, mi) + end +end + +# `OverlayMethodTable` +# -------------------- +import Base.Experimental: @MethodTable, @overlay + +@newinterp MTOverlayInterp +@MethodTable(OverlayedMT) +CC.method_table(interp::MTOverlayInterp) = CC.OverlayMethodTable(CC.get_world_counter(interp), OverlayedMT) + +@overlay OverlayedMT sin(x::Float64) = 1 +@test Base.return_types((Int,), MTOverlayInterp()) do x + sin(x) +end == Any[Int] From d15704aad45c33839c36dd3d24fd90ff2a063fa0 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Mon, 7 Mar 2022 13:16:37 +0900 Subject: [PATCH 30/46] `AbstractInterpreter`: implement `findsup` for `OverlayMethodTable` (#44448) --- base/compiler/abstractinterpretation.jl | 3 +- base/compiler/methodtable.jl | 61 +++++++++++++++---------- base/reflection.jl | 12 ++--- src/gf.c | 23 +++++----- stdlib/Test/src/Test.jl | 2 +- test/compiler/AbstractInterpreter.jl | 18 ++++++++ 6 files changed, 75 insertions(+), 44 deletions(-) diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index 53cc5fdeddf09..cf261367a642f 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -1476,7 +1476,8 @@ function abstract_invoke(interp::AbstractInterpreter, (; fargs, argtypes)::ArgIn argtype = Tuple{ft, argtype.parameters...} result = findsup(types, method_table(interp)) result === nothing && return CallMeta(Any, false) - method, valid_worlds = result + match, valid_worlds = result + method = match.method update_valid_age!(sv, valid_worlds) (ti, env::SimpleVector) = ccall(:jl_type_intersection_with_env, Any, (Any, Any), nargtype, method.sig)::SimpleVector (; rt, edge) = result = abstract_call_method(interp, method, ti, env, false, sv) diff --git a/base/compiler/methodtable.jl b/base/compiler/methodtable.jl index 4086023a725f0..841a020b43a8d 100644 --- a/base/compiler/methodtable.jl +++ b/base/compiler/methodtable.jl @@ -40,7 +40,7 @@ end getindex(result::MethodLookupResult, idx::Int) = getindex(result.matches, idx)::MethodMatch """ - findall(sig::Type, view::MethodTableView; limit=typemax(Int)) + findall(sig::Type, view::MethodTableView; limit::Int=typemax(Int)) -> MethodLookupResult or missing Find all methods in the given method table `view` that are applicable to the given signature `sig`. If no applicable methods are found, an empty result is @@ -48,37 +48,43 @@ returned. If the number of applicable methods exceeded the specified limit, `missing` is returned. """ function findall(@nospecialize(sig::Type), table::InternalMethodTable; limit::Int=typemax(Int)) - _min_val = RefValue{UInt}(typemin(UInt)) - _max_val = RefValue{UInt}(typemax(UInt)) - _ambig = RefValue{Int32}(0) - ms = _methods_by_ftype(sig, nothing, limit, table.world, false, _min_val, _max_val, _ambig) - if ms === false - return missing - end - return MethodLookupResult(ms::Vector{Any}, WorldRange(_min_val[], _max_val[]), _ambig[] != 0) + return _findall(sig, nothing, table.world, limit) end function findall(@nospecialize(sig::Type), table::OverlayMethodTable; limit::Int=typemax(Int)) + result = _findall(sig, table.mt, table.world, limit) + result === missing && return missing + if !isempty(result) + if all(match->match.fully_covers, result) + # no need to fall back to the internal method table + return result + else + # merge the match results with the internal method table + fallback_result = _findall(sig, nothing, table.world, limit) + return MethodLookupResult( + vcat(result.matches, fallback_result.matches), + WorldRange(min(result.valid_worlds.min_world, fallback_result.valid_worlds.min_world), + max(result.valid_worlds.max_world, fallback_result.valid_worlds.max_world)), + result.ambig | fallback_result.ambig) + end + end + # fall back to the internal method table + return _findall(sig, nothing, table.world, limit) +end + +function _findall(@nospecialize(sig::Type), mt::Union{Nothing,Core.MethodTable}, world::UInt, limit::Int) _min_val = RefValue{UInt}(typemin(UInt)) _max_val = RefValue{UInt}(typemax(UInt)) _ambig = RefValue{Int32}(0) - ms = _methods_by_ftype(sig, table.mt, limit, table.world, false, _min_val, _max_val, _ambig) + ms = _methods_by_ftype(sig, mt, limit, world, false, _min_val, _max_val, _ambig) if ms === false return missing - elseif isempty(ms) - # fall back to the internal method table - _min_val[] = typemin(UInt) - _max_val[] = typemax(UInt) - ms = _methods_by_ftype(sig, nothing, limit, table.world, false, _min_val, _max_val, _ambig) - if ms === false - return missing - end end return MethodLookupResult(ms::Vector{Any}, WorldRange(_min_val[], _max_val[]), _ambig[] != 0) end """ - findsup(sig::Type, view::MethodTableView)::Union{Tuple{MethodMatch, WorldRange}, Nothing} + findsup(sig::Type, view::MethodTableView) -> Tuple{MethodMatch, WorldRange} or nothing Find the (unique) method `m` such that `sig <: m.sig`, while being more specific than any other method with the same property. In other words, find @@ -92,12 +98,21 @@ upper bound of `sig`, or it is possible that among the upper bounds, there is no least element. In both cases `nothing` is returned. """ function findsup(@nospecialize(sig::Type), table::InternalMethodTable) + return _findsup(sig, nothing, table.world) +end + +function findsup(@nospecialize(sig::Type), table::OverlayMethodTable) + result = _findsup(sig, table.mt, table.world) + result === nothing || return result + return _findsup(sig, nothing, table.world) # fall back to the internal method table +end + +function _findsup(@nospecialize(sig::Type), mt::Union{Nothing,Core.MethodTable}, world::UInt) min_valid = RefValue{UInt}(typemin(UInt)) max_valid = RefValue{UInt}(typemax(UInt)) - result = ccall(:jl_gf_invoke_lookup_worlds, Any, (Any, UInt, Ptr{Csize_t}, Ptr{Csize_t}), - sig, table.world, min_valid, max_valid)::Union{MethodMatch, Nothing} - result === nothing && return nothing - (result.method, WorldRange(min_valid[], max_valid[])) + result = ccall(:jl_gf_invoke_lookup_worlds, Any, (Any, Any, UInt, Ptr{Csize_t}, Ptr{Csize_t}), + sig, mt, world, min_valid, max_valid)::Union{MethodMatch, Nothing} + return result === nothing ? result : (result, WorldRange(min_valid[], max_valid[])) end isoverlayed(::MethodTableView) = error("unsatisfied MethodTableView interface") diff --git a/base/reflection.jl b/base/reflection.jl index 5490cae9511c8..0ae3b087fc022 100644 --- a/base/reflection.jl +++ b/base/reflection.jl @@ -1347,15 +1347,11 @@ end print_statement_costs(args...; kwargs...) = print_statement_costs(stdout, args...; kwargs...) function _which(@nospecialize(tt::Type), world=get_world_counter()) - min_valid = RefValue{UInt}(typemin(UInt)) - max_valid = RefValue{UInt}(typemax(UInt)) - match = ccall(:jl_gf_invoke_lookup_worlds, Any, - (Any, UInt, Ptr{Csize_t}, Ptr{Csize_t}), - tt, world, min_valid, max_valid) - if match === nothing + result = Core.Compiler._findsup(tt, nothing, world) + if result === nothing error("no unique matching method found for the specified argument types") end - return match::Core.MethodMatch + return first(result)::Core.MethodMatch end """ @@ -1478,7 +1474,7 @@ true function hasmethod(@nospecialize(f), @nospecialize(t); world::UInt=get_world_counter()) t = to_tuple_type(t) t = signature_type(f, t) - return ccall(:jl_gf_invoke_lookup, Any, (Any, UInt), t, world) !== nothing + return ccall(:jl_gf_invoke_lookup, Any, (Any, Any, UInt), t, nothing, world) !== nothing end function hasmethod(@nospecialize(f), @nospecialize(t), kwnames::Tuple{Vararg{Symbol}}; world::UInt=get_world_counter()) diff --git a/src/gf.c b/src/gf.c index 2b5d17c408299..964e4d1e01963 100644 --- a/src/gf.c +++ b/src/gf.c @@ -1217,7 +1217,7 @@ static jl_method_instance_t *cache_method( return newmeth; } -static jl_method_match_t *_gf_invoke_lookup(jl_value_t *types JL_PROPAGATES_ROOT, size_t world, size_t *min_valid, size_t *max_valid); +static jl_method_match_t *_gf_invoke_lookup(jl_value_t *types JL_PROPAGATES_ROOT, jl_value_t *mt, size_t world, size_t *min_valid, size_t *max_valid); static jl_method_instance_t *jl_mt_assoc_by_type(jl_methtable_t *mt JL_PROPAGATES_ROOT, jl_datatype_t *tt, size_t world) { @@ -1237,7 +1237,7 @@ static jl_method_instance_t *jl_mt_assoc_by_type(jl_methtable_t *mt JL_PROPAGATE size_t min_valid = 0; size_t max_valid = ~(size_t)0; - jl_method_match_t *matc = _gf_invoke_lookup((jl_value_t*)tt, world, &min_valid, &max_valid); + jl_method_match_t *matc = _gf_invoke_lookup((jl_value_t*)tt, jl_nothing, world, &min_valid, &max_valid); jl_method_instance_t *nf = NULL; if (matc) { JL_GC_PUSH1(&matc); @@ -2540,36 +2540,37 @@ JL_DLLEXPORT jl_value_t *jl_apply_generic(jl_value_t *F, jl_value_t **args, uint return _jl_invoke(F, args, nargs, mfunc, world); } -static jl_method_match_t *_gf_invoke_lookup(jl_value_t *types JL_PROPAGATES_ROOT, size_t world, size_t *min_valid, size_t *max_valid) +static jl_method_match_t *_gf_invoke_lookup(jl_value_t *types JL_PROPAGATES_ROOT, jl_value_t *mt, size_t world, size_t *min_valid, size_t *max_valid) { jl_value_t *unw = jl_unwrap_unionall((jl_value_t*)types); if (jl_is_tuple_type(unw) && jl_tparam0(unw) == jl_bottom_type) return NULL; - jl_methtable_t *mt = jl_method_table_for(unw); - if ((jl_value_t*)mt == jl_nothing) + if (mt == jl_nothing) + mt = (jl_value_t*)jl_method_table_for(unw); + if (mt == jl_nothing) mt = NULL; - jl_value_t *matches = ml_matches(mt, (jl_tupletype_t*)types, 1, 0, 0, world, 1, min_valid, max_valid, NULL); + jl_value_t *matches = ml_matches((jl_methtable_t*)mt, (jl_tupletype_t*)types, 1, 0, 0, world, 1, min_valid, max_valid, NULL); if (matches == jl_false || jl_array_len(matches) != 1) return NULL; jl_method_match_t *matc = (jl_method_match_t*)jl_array_ptr_ref(matches, 0); return matc; } -JL_DLLEXPORT jl_value_t *jl_gf_invoke_lookup(jl_value_t *types, size_t world) +JL_DLLEXPORT jl_value_t *jl_gf_invoke_lookup(jl_value_t *types, jl_value_t *mt, size_t world) { // Deprecated: Use jl_gf_invoke_lookup_worlds for future development size_t min_valid = 0; size_t max_valid = ~(size_t)0; - jl_method_match_t *matc = _gf_invoke_lookup(types, world, &min_valid, &max_valid); + jl_method_match_t *matc = _gf_invoke_lookup(types, mt, world, &min_valid, &max_valid); if (matc == NULL) return jl_nothing; return (jl_value_t*)matc->method; } -JL_DLLEXPORT jl_value_t *jl_gf_invoke_lookup_worlds(jl_value_t *types, size_t world, size_t *min_world, size_t *max_world) +JL_DLLEXPORT jl_value_t *jl_gf_invoke_lookup_worlds(jl_value_t *types, jl_value_t *mt, size_t world, size_t *min_world, size_t *max_world) { - jl_method_match_t *matc = _gf_invoke_lookup(types, world, min_world, max_world); + jl_method_match_t *matc = _gf_invoke_lookup(types, mt, world, min_world, max_world); if (matc == NULL) return jl_nothing; return (jl_value_t*)matc; @@ -2590,7 +2591,7 @@ jl_value_t *jl_gf_invoke(jl_value_t *types0, jl_value_t *gf, jl_value_t **args, jl_value_t *types = NULL; JL_GC_PUSH1(&types); types = jl_argtype_with_function(gf, types0); - jl_method_t *method = (jl_method_t*)jl_gf_invoke_lookup(types, world); + jl_method_t *method = (jl_method_t*)jl_gf_invoke_lookup(types, jl_nothing, world); JL_GC_PROMISE_ROOTED(method); if ((jl_value_t*)method == jl_nothing) { diff --git a/stdlib/Test/src/Test.jl b/stdlib/Test/src/Test.jl index 5693d65c7f913..95cd1ecccd9c3 100644 --- a/stdlib/Test/src/Test.jl +++ b/stdlib/Test/src/Test.jl @@ -1774,7 +1774,7 @@ function detect_unbound_args(mods...; params = tuple_sig.parameters[1:(end - 1)] tuple_sig = Base.rewrap_unionall(Tuple{params...}, m.sig) world = Base.get_world_counter() - mf = ccall(:jl_gf_invoke_lookup, Any, (Any, UInt), tuple_sig, world) + mf = ccall(:jl_gf_invoke_lookup, Any, (Any, Any, UInt), tuple_sig, nothing, world) if mf !== nothing && mf !== m && mf.sig <: tuple_sig continue end diff --git a/test/compiler/AbstractInterpreter.jl b/test/compiler/AbstractInterpreter.jl index 6ef2adf7177fa..f1fe4b06dcb63 100644 --- a/test/compiler/AbstractInterpreter.jl +++ b/test/compiler/AbstractInterpreter.jl @@ -45,3 +45,21 @@ CC.method_table(interp::MTOverlayInterp) = CC.OverlayMethodTable(CC.get_world_co @test Base.return_types((Int,), MTOverlayInterp()) do x sin(x) end == Any[Int] +@test Base.return_types((Any,), MTOverlayInterp()) do x + Base.@invoke sin(x::Float64) +end == Any[Int] + +# fallback to the internal method table +@test Base.return_types((Int,), MTOverlayInterp()) do x + cos(x) +end == Any[Float64] +@test Base.return_types((Any,), MTOverlayInterp()) do x + Base.@invoke cos(x::Float64) +end == Any[Float64] + +# not fully covered overlay method match +overlay_match(::Any) = nothing +@overlay OverlayedMT overlay_match(::Int) = missing +@test Base.return_types((Any,), MTOverlayInterp()) do x + overlay_match(x) +end == Any[Union{Nothing,Missing}] From 0a4a8506ace84cb2cdc7614e1bbb3f7c7109bc0f Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Wed, 9 Mar 2022 16:34:11 +0900 Subject: [PATCH 31/46] follow up #44448, correct `findall`/`findsup` for `OverlayMethodTable` (#44511) - respect world range of failed lookup into `OverlayMethodTable`: - fix calculation of merged valid world range: - make `findsup` return valid `WorldRange` unconditionally, and enable more strict world validation within `abstract_invoke`: - fix the default `limit::Int` value of `findall` --- base/compiler/abstractinterpretation.jl | 7 ++-- base/compiler/methodtable.jl | 46 ++++++++++++++----------- base/reflection.jl | 6 ++-- 3 files changed, 31 insertions(+), 28 deletions(-) diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index cf261367a642f..14f37ff87c464 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -1474,11 +1474,10 @@ function abstract_invoke(interp::AbstractInterpreter, (; fargs, argtypes)::ArgIn types = rewrap_unionall(Tuple{ft, unwrap_unionall(types).parameters...}, types)::Type nargtype = Tuple{ft, nargtype.parameters...} argtype = Tuple{ft, argtype.parameters...} - result = findsup(types, method_table(interp)) - result === nothing && return CallMeta(Any, false) - match, valid_worlds = result - method = match.method + match, valid_worlds = findsup(types, method_table(interp)) + match === nothing && return CallMeta(Any, false) update_valid_age!(sv, valid_worlds) + method = match.method (ti, env::SimpleVector) = ccall(:jl_type_intersection_with_env, Any, (Any, Any), nargtype, method.sig)::SimpleVector (; rt, edge) = result = abstract_call_method(interp, method, ti, env, false, sv) edge !== nothing && add_backedge!(edge::MethodInstance, sv) diff --git a/base/compiler/methodtable.jl b/base/compiler/methodtable.jl index 841a020b43a8d..f68cdd52d1b06 100644 --- a/base/compiler/methodtable.jl +++ b/base/compiler/methodtable.jl @@ -47,29 +47,28 @@ given signature `sig`. If no applicable methods are found, an empty result is returned. If the number of applicable methods exceeded the specified limit, `missing` is returned. """ -function findall(@nospecialize(sig::Type), table::InternalMethodTable; limit::Int=typemax(Int)) +function findall(@nospecialize(sig::Type), table::InternalMethodTable; limit::Int=Int(typemax(Int32))) return _findall(sig, nothing, table.world, limit) end -function findall(@nospecialize(sig::Type), table::OverlayMethodTable; limit::Int=typemax(Int)) +function findall(@nospecialize(sig::Type), table::OverlayMethodTable; limit::Int=Int(typemax(Int32))) result = _findall(sig, table.mt, table.world, limit) result === missing && return missing - if !isempty(result) - if all(match->match.fully_covers, result) - # no need to fall back to the internal method table - return result - else - # merge the match results with the internal method table - fallback_result = _findall(sig, nothing, table.world, limit) - return MethodLookupResult( - vcat(result.matches, fallback_result.matches), - WorldRange(min(result.valid_worlds.min_world, fallback_result.valid_worlds.min_world), - max(result.valid_worlds.max_world, fallback_result.valid_worlds.max_world)), - result.ambig | fallback_result.ambig) - end + nr = length(result) + if nr ≥ 1 && result[nr].fully_covers + # no need to fall back to the internal method table + return result end # fall back to the internal method table - return _findall(sig, nothing, table.world, limit) + fallback_result = _findall(sig, nothing, table.world, limit) + fallback_result === missing && return missing + # merge the fallback match results with the internal method table + return MethodLookupResult( + vcat(result.matches, fallback_result.matches), + WorldRange( + max(result.valid_worlds.min_world, fallback_result.valid_worlds.min_world), + min(result.valid_worlds.max_world, fallback_result.valid_worlds.max_world)), + result.ambig | fallback_result.ambig) end function _findall(@nospecialize(sig::Type), mt::Union{Nothing,Core.MethodTable}, world::UInt, limit::Int) @@ -102,17 +101,22 @@ function findsup(@nospecialize(sig::Type), table::InternalMethodTable) end function findsup(@nospecialize(sig::Type), table::OverlayMethodTable) - result = _findsup(sig, table.mt, table.world) - result === nothing || return result - return _findsup(sig, nothing, table.world) # fall back to the internal method table + match, valid_worlds = _findsup(sig, table.mt, table.world) + match !== nothing && return match, valid_worlds + # fall back to the internal method table + fallback_match, fallback_valid_worlds = _findsup(sig, nothing, table.world) + return fallback_match, WorldRange( + max(valid_worlds.min_world, fallback_valid_worlds.min_world), + min(valid_worlds.max_world, fallback_valid_worlds.max_world)) end function _findsup(@nospecialize(sig::Type), mt::Union{Nothing,Core.MethodTable}, world::UInt) min_valid = RefValue{UInt}(typemin(UInt)) max_valid = RefValue{UInt}(typemax(UInt)) - result = ccall(:jl_gf_invoke_lookup_worlds, Any, (Any, Any, UInt, Ptr{Csize_t}, Ptr{Csize_t}), + match = ccall(:jl_gf_invoke_lookup_worlds, Any, (Any, Any, UInt, Ptr{Csize_t}, Ptr{Csize_t}), sig, mt, world, min_valid, max_valid)::Union{MethodMatch, Nothing} - return result === nothing ? result : (result, WorldRange(min_valid[], max_valid[])) + valid_worlds = WorldRange(min_valid[], max_valid[]) + return match, valid_worlds end isoverlayed(::MethodTableView) = error("unsatisfied MethodTableView interface") diff --git a/base/reflection.jl b/base/reflection.jl index 0ae3b087fc022..95fb81c8859d6 100644 --- a/base/reflection.jl +++ b/base/reflection.jl @@ -1347,11 +1347,11 @@ end print_statement_costs(args...; kwargs...) = print_statement_costs(stdout, args...; kwargs...) function _which(@nospecialize(tt::Type), world=get_world_counter()) - result = Core.Compiler._findsup(tt, nothing, world) - if result === nothing + match, _ = Core.Compiler._findsup(tt, nothing, world) + if match === nothing error("no unique matching method found for the specified argument types") end - return first(result)::Core.MethodMatch + return match end """ From d14209d58bbdd132490bb94a9749832960f3a7b9 Mon Sep 17 00:00:00 2001 From: Oscar Smith Date: Tue, 8 Mar 2022 11:28:07 -0500 Subject: [PATCH 32/46] fix negative numbers to powers >2^64 (#44456) *fix negative numbers to powers >2^64 (cherry picked from commit 03433a20a848ee1c07cfcae6283ec25e01b49a18) --- base/math.jl | 4 ++++ test/math.jl | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/base/math.jl b/base/math.jl index af86c11c01b26..1fb10467e184f 100644 --- a/base/math.jl +++ b/base/math.jl @@ -998,6 +998,8 @@ end @constprop :aggressive function ^(x::Float64, y::Float64) yint = unsafe_trunc(Int, y) # Note, this is actually safe since julia freezes the result y == yint && return x^yint + #numbers greater than 2*inv(eps(T)) must be even, and the pow will overflow + y >= 2*inv(eps()) && return x^(typemax(Int64)-1) x<0 && y > -4e18 && throw_exp_domainerror(x) # |y| is small enough that y isn't an integer x == 1 && return 1.0 return pow_body(x, y) @@ -1016,6 +1018,8 @@ end @constprop :aggressive function ^(x::T, y::T) where T <: Union{Float16, Float32} yint = unsafe_trunc(Int64, y) # Note, this is actually safe since julia freezes the result y == yint && return x^yint + #numbers greater than 2*inv(eps(T)) must be even, and the pow will overflow + y >= 2*inv(eps(T)) && return x^(typemax(Int64)-1) x < 0 && y > -4e18 && throw_exp_domainerror(x) # |y| is small enough that y isn't an integer return pow_body(x, y) end diff --git a/test/math.jl b/test/math.jl index af280066f2f22..22bb026ceed0c 100644 --- a/test/math.jl +++ b/test/math.jl @@ -155,6 +155,10 @@ end @test x^y === T(big(x)^big(y)) @test x^1 === x @test x^yi === T(big(x)^yi) + # test (-x)^y for y larger than typemax(Int) + @test T(-1)^floatmax(T) === T(1) + @test prevfloat(T(-1))^floatmax(T) === T(Inf) + @test nextfloat(T(-1))^floatmax(T) === T(0.0) # test for large negative exponent where error compensation matters @test 0.9999999955206014^-1.0e8 == 1.565084574870928 @test (-x)^yi == x^yi From 225cb1db4171079f0258753dd5205b6972c4227a Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Tue, 8 Mar 2022 19:24:08 +0100 Subject: [PATCH 33/46] remove deprecation warning for `@_inline_meta` (#44516) (cherry picked from commit 02abca3c293abdded1b3fa3629ced944c7a4e27b) --- base/deprecated.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/base/deprecated.jl b/base/deprecated.jl index 6709023147283..1af38ebcdac1c 100644 --- a/base/deprecated.jl +++ b/base/deprecated.jl @@ -266,8 +266,8 @@ end # BEGIN 1.8 deprecations -@deprecate var"@_inline_meta" var"@inline" false -@deprecate var"@_noinline_meta" var"@noinline" false +const var"@_inline_meta" = var"@inline" +const var"@_noinline_meta" = var"@noinline" @deprecate getindex(t::Tuple, i::Real) t[convert(Int, i)] # END 1.8 deprecations From 19ce653c00d1a539c7026850d98ee45cd401bc0f Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Tue, 8 Mar 2022 15:31:33 -0500 Subject: [PATCH 34/46] process: ensure uvfinalize and _uv_close_cb are synchronized (#44476) There appeared to be a possibility they could race and the data field might already be destroyed before we reached the close callback, from looking at the state of the program when reproducing #44460. This is because the uv_return_spawn set the handle to NULL, which later can cause the uvfinalize to exit early (if the finalizer gets run on another thread, since we have disabled finalizers on our thread). Then the GC can reap the julia Process object prior to uv_close cleaning up the object. We solve this by calling disassociate_julia_struct before dropping the reference to the handle. But then we also fully address any remaining race condition by having uvfinalize acquire a lock also. The uv_return_spawn callback also needs to be synchronized with the constructor, since we might have arrived there before we finished allocating the Process struct here, leading to missed exit events. Fixes #44460 (cherry picked from commit c591bf2f412c208c00e55ee503db840104aaca45) --- base/process.jl | 24 +++++++++++++++++------- src/jl_uv.c | 4 ++-- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/base/process.jl b/base/process.jl index 6aac514191681..cbc251ed6dbca 100644 --- a/base/process.jl +++ b/base/process.jl @@ -38,9 +38,13 @@ pipe_writer(p::ProcessChain) = p.in # release ownership of the libuv handle function uvfinalize(proc::Process) if proc.handle != C_NULL - disassociate_julia_struct(proc.handle) - ccall(:jl_close_uv, Cvoid, (Ptr{Cvoid},), proc.handle) - proc.handle = C_NULL + iolock_begin() + if proc.handle != C_NULL + disassociate_julia_struct(proc.handle) + ccall(:jl_close_uv, Cvoid, (Ptr{Cvoid},), proc.handle) + proc.handle = C_NULL + end + iolock_end() end nothing end @@ -52,6 +56,7 @@ function uv_return_spawn(p::Ptr{Cvoid}, exit_status::Int64, termsignal::Int32) proc = unsafe_pointer_to_objref(data)::Process proc.exitcode = exit_status proc.termsignal = termsignal + disassociate_julia_struct(proc) # ensure that data field is set to C_NULL ccall(:jl_close_uv, Cvoid, (Ptr{Cvoid},), proc.handle) proc.handle = C_NULL lock(proc.exitnotify) @@ -95,8 +100,9 @@ end end for io in stdio] handle = Libc.malloc(_sizeof_uv_process) - disassociate_julia_struct(handle) # ensure that data field is set to C_NULL + disassociate_julia_struct(handle) (; exec, flags, env, dir) = cmd + iolock_begin() err = ccall(:jl_spawn, Int32, (Cstring, Ptr{Cstring}, Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Tuple{Cint, UInt}}, Int, @@ -109,13 +115,17 @@ end cpumask === nothing ? C_NULL : cpumask, cpumask === nothing ? 0 : length(cpumask), @cfunction(uv_return_spawn, Cvoid, (Ptr{Cvoid}, Int64, Int32))) + if err == 0 + pp = Process(cmd, handle) + associate_julia_struct(handle, pp) + else + ccall(:jl_forceclose_uv, Cvoid, (Ptr{Cvoid},), handle) # will call free on handle eventually + end + iolock_end() end if err != 0 - ccall(:jl_forceclose_uv, Cvoid, (Ptr{Cvoid},), handle) # will call free on handle eventually throw(_UVError("could not spawn " * repr(cmd), err)) end - pp = Process(cmd, handle) - associate_julia_struct(handle, pp) return pp end diff --git a/src/jl_uv.c b/src/jl_uv.c index d2372b59c4670..d2a78c26bbc72 100644 --- a/src/jl_uv.c +++ b/src/jl_uv.c @@ -282,7 +282,7 @@ JL_DLLEXPORT void jl_uv_disassociate_julia_struct(uv_handle_t *handle) handle->data = NULL; } -#define UV_CLOSED 0x02 // UV_HANDLE_CLOSED on Windows (same value) +#define UV_HANDLE_CLOSED 0x02 JL_DLLEXPORT int jl_spawn(char *name, char **argv, uv_loop_t *loop, uv_process_t *proc, @@ -308,7 +308,7 @@ JL_DLLEXPORT int jl_spawn(char *name, char **argv, if (!(flags == UV_INHERIT_FD || flags == UV_INHERIT_STREAM || flags == UV_IGNORE)) { proc->type = UV_PROCESS; proc->loop = loop; - proc->flags = UV_CLOSED; + proc->flags = UV_HANDLE_CLOSED; return UV_EINVAL; } } From 390551910a84fd08be330eac333a5dad2b0c549a Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Tue, 8 Mar 2022 15:31:54 -0500 Subject: [PATCH 35/46] ensure invoke kwargs work on Types (#44464) Fix #44227 (cherry picked from commit f731c38bf84604443f0760b114957e40f2b10fa2) --- src/builtins.c | 4 ++-- test/core.jl | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/builtins.c b/src/builtins.c index ca2f56adaf6d8..11da13285e9ca 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -1286,7 +1286,7 @@ JL_CALLABLE(jl_f_invoke_kwsorter) if (nt < jl_page_size/sizeof(jl_value_t*)) { jl_value_t **types = (jl_value_t**)alloca(nt*sizeof(jl_value_t*)); types[0] = (jl_value_t*)jl_namedtuple_type; - types[1] = jl_typeof(func); + types[1] = jl_is_type(func) ? (jl_value_t*)jl_wrap_Type(func) : jl_typeof(func); for (i = 2; i < nt; i++) types[i] = jl_tparam(argtypes, i - 2); argtypes = (jl_value_t*)jl_apply_tuple_type_v(types, nt); @@ -1295,7 +1295,7 @@ JL_CALLABLE(jl_f_invoke_kwsorter) jl_svec_t *types = jl_alloc_svec_uninit(nt); JL_GC_PUSH1(&types); jl_svecset(types, 0, jl_namedtuple_type); - jl_svecset(types, 1, jl_typeof(func)); + jl_svecset(types, 1, jl_is_type(func) ? (jl_value_t*)jl_wrap_Type(func) : jl_typeof(func)); for (i = 2; i < nt; i++) jl_svecset(types, i, jl_tparam(argtypes, i - 2)); argtypes = (jl_value_t*)jl_apply_tuple_type(types); diff --git a/test/core.jl b/test/core.jl index 6dbd8f3d9fa0e..93ba97df60420 100644 --- a/test/core.jl +++ b/test/core.jl @@ -1524,6 +1524,12 @@ let @test invoke(i2169, Tuple{Array}, Int8[1]) === Int8(-128) end +# issue #44227 +struct F{T} end +F{Int32}(; y=1) = 1 +F{Int64}(; y=1) = invoke(F{Int32}, Tuple{}; y) +@test F{Int64}() === 1 + # issue #2365 mutable struct B2365{T} v::Union{T, Nothing} From ba660cfa52463f7efcb5d93fea97761ea38ee3b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mos=C3=A8=20Giordano?= Date: Wed, 9 Mar 2022 01:44:19 +0000 Subject: [PATCH 36/46] [CompilerSupportLibraries_jll] Update to v0.5.2 (#44487) The main difference since previous version should be the libraries for aarch64-apple-darwin, which are based on a more recent version of the GCC fork for this platform. There are a couple of notable ABI changes here: * `libgcc_s` is now called `libgcc_s.1.1.dylib` instead of `libgcc_s.2.dylib` * there is now `libquadmath.0.dylib` for this platform, which was missing before. (cherry picked from commit cb2fa5d8483906f6e4c3b47f975e1c5ee2819d04) --- Make.inc | 4 +- base/Makefile | 4 + deps/checksums/compilersupportlibraries | 184 +++++++++--------- .../CompilerSupportLibraries_jll/Project.toml | 2 +- .../src/CompilerSupportLibraries_jll.jl | 2 +- 5 files changed, 100 insertions(+), 96 deletions(-) diff --git a/Make.inc b/Make.inc index a95eab1ec1abe..a143b871efecb 100644 --- a/Make.inc +++ b/Make.inc @@ -1,4 +1,4 @@ -# -*- mode: makefile-gmake -*- +# -*- mode: makefile -*- # vi:syntax=make ## Note: @@ -1472,7 +1472,7 @@ endif endif ifeq ($(OS),Darwin) ifeq ($(ARCH),aarch64) -LIBGCC_NAME := libgcc_s.2.$(SHLIB_EXT) +LIBGCC_NAME := libgcc_s.1.1.$(SHLIB_EXT) else LIBGCC_NAME := libgcc_s.1.$(SHLIB_EXT) endif diff --git a/base/Makefile b/base/Makefile index f3ed73791085e..23a9c4011131e 100644 --- a/base/Makefile +++ b/base/Makefile @@ -206,7 +206,11 @@ else ifneq ($(USE_SYSTEM_OPENLIBM),0) $(eval $(call symlink_system_library,OPENLIBM,$(LIBMNAME))) endif +ifeq ($(APPLE_ARCH),arm64) +$(eval $(call symlink_system_library,CSL,libgcc_s,1.1)) +else $(eval $(call symlink_system_library,CSL,libgcc_s,1)) +endif ifneq (,$(LIBGFORTRAN_VERSION)) $(eval $(call symlink_system_library,CSL,libgfortran,$(LIBGFORTRAN_VERSION))) endif diff --git a/deps/checksums/compilersupportlibraries b/deps/checksums/compilersupportlibraries index e351d100cb481..86250fdc63390 100644 --- a/deps/checksums/compilersupportlibraries +++ b/deps/checksums/compilersupportlibraries @@ -1,92 +1,92 @@ -CompilerSupportLibraries.v0.5.0+0.aarch64-apple-darwin-libgfortran5.tar.gz/md5/307711def378e337a999c182aa7e07d8 -CompilerSupportLibraries.v0.5.0+0.aarch64-apple-darwin-libgfortran5.tar.gz/sha512/0dcad5e315e045397320f667b27fc378da898ebfea9b55a2837e68b29434fe2c2ddc9652cc75a4551062ce70a2bfaffa8223c77398aa41fe1a73ccb44952cd8f -CompilerSupportLibraries.v0.5.0+0.aarch64-linux-gnu-libgfortran3.tar.gz/md5/177f2665038919c3f8ed968226ff3b56 -CompilerSupportLibraries.v0.5.0+0.aarch64-linux-gnu-libgfortran3.tar.gz/sha512/ea67c3b9986106aee12e5f22ab3d3c5d71a58759a7d20a7724bbb198e5c71f42fa2034e46f3147006a2d2277b3881f0546030d1040cb9393e58eeae87eb82c4d -CompilerSupportLibraries.v0.5.0+0.aarch64-linux-gnu-libgfortran4.tar.gz/md5/f16db35be9018a5c61eaafaaf7226d10 -CompilerSupportLibraries.v0.5.0+0.aarch64-linux-gnu-libgfortran4.tar.gz/sha512/051b5a0dd2235eaa90557e487c83499b3d7e0b9e921f7b2f14e77c81152c338acd5bac8040bdf6679db656cd8039093db43565f843dede253717425e464e61b0 -CompilerSupportLibraries.v0.5.0+0.aarch64-linux-gnu-libgfortran5.tar.gz/md5/e6082f3e46b627fdaef09f1ef81c1d7b -CompilerSupportLibraries.v0.5.0+0.aarch64-linux-gnu-libgfortran5.tar.gz/sha512/13d0ab1c0e84a65db729ea6bd45a868d9d65e1a0ec95412448846d1044e2bbf11b11d96cfa576dccf3d7eccc4bed4eb9ae4bac0989e9b1b97adad5e404dfe4a4 -CompilerSupportLibraries.v0.5.0+0.aarch64-linux-musl-libgfortran3.tar.gz/md5/00703177897f8c46a577c2b0518432bc -CompilerSupportLibraries.v0.5.0+0.aarch64-linux-musl-libgfortran3.tar.gz/sha512/af14ad1303f3918dd691e0b509ea0fd52ac7c9f0c285e8dbb741bd34ce0b1927f89f219fcf8d260315c503b18bf98b3df117810328066a9964917cc34968ce98 -CompilerSupportLibraries.v0.5.0+0.aarch64-linux-musl-libgfortran4.tar.gz/md5/f823b692319cd370ca59189ad2ba4a3d -CompilerSupportLibraries.v0.5.0+0.aarch64-linux-musl-libgfortran4.tar.gz/sha512/b0c4131bf4d15c482bbed83fcc570da2f7bb8ef99d507e0e13eb0c8f5519ec73ff234c58d505294be3f8d39b6dd1c7022578db02005ae111c7873243e8ddc8ef -CompilerSupportLibraries.v0.5.0+0.aarch64-linux-musl-libgfortran5.tar.gz/md5/a9ef1a68518058fe6c945e8b00f8400f -CompilerSupportLibraries.v0.5.0+0.aarch64-linux-musl-libgfortran5.tar.gz/sha512/6aa53edf48a17ec8515cad5c79a15ab0e40cc44c9ffb188fd57fc560dde7a99d6487ead6e4caafaa9912c6590c6a391f914016fd4342589da09d56c657ad2c07 -CompilerSupportLibraries.v0.5.0+0.armv6l-linux-gnueabihf-libgfortran3.tar.gz/md5/d3aaf50955ad671917e941e0dcf3803f -CompilerSupportLibraries.v0.5.0+0.armv6l-linux-gnueabihf-libgfortran3.tar.gz/sha512/72983b2272300c2332cfe6864b5dd5249bbbb181bd65b10bf6bfb3a37e5e582bb9c159db0b63a077066a325899a2864717f28c60c85027be3b637bb80f994e52 -CompilerSupportLibraries.v0.5.0+0.armv6l-linux-gnueabihf-libgfortran4.tar.gz/md5/e221d51df9b18b2562a0f3e8dc8012cd -CompilerSupportLibraries.v0.5.0+0.armv6l-linux-gnueabihf-libgfortran4.tar.gz/sha512/758b07b4a559dda747574649926333a70355e2d80acb2ea37bb39777c0b1cecf8f308a5f8062110c378db2230ec8baf23385ae313d1c58de8bfc651573c64c1f -CompilerSupportLibraries.v0.5.0+0.armv6l-linux-gnueabihf-libgfortran5.tar.gz/md5/96f7feef9b1dd7944130de2e9cda68b8 -CompilerSupportLibraries.v0.5.0+0.armv6l-linux-gnueabihf-libgfortran5.tar.gz/sha512/8b4aaff1388cd506bef7f3a9edd42ed8ee1db468a18d34cd5d58d7da305853dbf48d4665e99c06c6fb0115e421d19dba5c36e947cb06defe7f479a05b547f112 -CompilerSupportLibraries.v0.5.0+0.armv6l-linux-musleabihf-libgfortran3.tar.gz/md5/a1e3642a7ce2b7834aa2f1b695a9977c -CompilerSupportLibraries.v0.5.0+0.armv6l-linux-musleabihf-libgfortran3.tar.gz/sha512/9d22b1fa8fa8eaaa5316cb494eb223e0fe73660aa5ca7518180e40d296d6d07a9863938501e5d5350bf79e79d975d7d66dca12768a0a69527d2c17baf7aaf345 -CompilerSupportLibraries.v0.5.0+0.armv6l-linux-musleabihf-libgfortran4.tar.gz/md5/d897098fd98928c2d644ed5ee26c3faa -CompilerSupportLibraries.v0.5.0+0.armv6l-linux-musleabihf-libgfortran4.tar.gz/sha512/4aad051f4f1e3d744825c650363a49f39e04cbd44dad25197ddee1890339e9441aa872f893478a2d8ff556c9a70a89c2885cd779ba3efd3c0f7193c386b820b7 -CompilerSupportLibraries.v0.5.0+0.armv6l-linux-musleabihf-libgfortran5.tar.gz/md5/c36bfd4c5b90d55c55bc18feaf51b134 -CompilerSupportLibraries.v0.5.0+0.armv6l-linux-musleabihf-libgfortran5.tar.gz/sha512/ab16c638780a0118b930ac587df81fa74d2731bf1af402266106e1ecb791df353c1f368a8e7fc9147d390825ff8624e600aae45f1f6ccfc0015ce131368452d7 -CompilerSupportLibraries.v0.5.0+0.armv7l-linux-gnueabihf-libgfortran3.tar.gz/md5/feb76551e6f7407de3006a3d363cee7a -CompilerSupportLibraries.v0.5.0+0.armv7l-linux-gnueabihf-libgfortran3.tar.gz/sha512/976f8e34e72231b013ea0418feff9c3c9efa7b9c34688aca115a03f2bade8760ca9f259f8f502ef5012fbb389f4bf365fd7639b066daca16fb7ec1d32b5cd789 -CompilerSupportLibraries.v0.5.0+0.armv7l-linux-gnueabihf-libgfortran4.tar.gz/md5/560ca43fa6dbd3f2e9052401477df165 -CompilerSupportLibraries.v0.5.0+0.armv7l-linux-gnueabihf-libgfortran4.tar.gz/sha512/333c7f4fbc172e7fd3d99e2673dbed1d9c699a5bb29a20095a255fadc89ded05abda755fc167aa8a16a4e93f524390c9c817df7b67fccdca88754d0301259977 -CompilerSupportLibraries.v0.5.0+0.armv7l-linux-gnueabihf-libgfortran5.tar.gz/md5/d3ac5f871599ab225a1128c302486345 -CompilerSupportLibraries.v0.5.0+0.armv7l-linux-gnueabihf-libgfortran5.tar.gz/sha512/adb706882e923978b6e18c7134578bc86ed4e031a7a0120222018cd1b8efcf530854e426b6442dbd80b8c77c3677f1906aedb12c0ddeb33efcdd3bcd2c4a109a -CompilerSupportLibraries.v0.5.0+0.armv7l-linux-musleabihf-libgfortran3.tar.gz/md5/58774aa398a63479af3f4c69678d0191 -CompilerSupportLibraries.v0.5.0+0.armv7l-linux-musleabihf-libgfortran3.tar.gz/sha512/fe9307e6fb0b54522495fc9cc48756a60fc79af27d9e73bfb3ee49cbb366dddec1beedca03614f15761b308bc28014205f174f673fa258e76d5947446b87b039 -CompilerSupportLibraries.v0.5.0+0.armv7l-linux-musleabihf-libgfortran4.tar.gz/md5/af1a8ce693ba307e61184f4023d73d67 -CompilerSupportLibraries.v0.5.0+0.armv7l-linux-musleabihf-libgfortran4.tar.gz/sha512/2ea581bb44408fc789ac306734736f6eb6cf0a15b234f43a6f50ae8f10014b5689f5aa8356112c2b54a86b9a7734ace3479c4e4aba1e5df636dda3dcd09b7e28 -CompilerSupportLibraries.v0.5.0+0.armv7l-linux-musleabihf-libgfortran5.tar.gz/md5/20d62064f495877f12b7e87e684ad43a -CompilerSupportLibraries.v0.5.0+0.armv7l-linux-musleabihf-libgfortran5.tar.gz/sha512/31b1c7c9fe3378e8bb788c897bbac0505a5ae70f500f3b1457325dbbb149c14224a88d17fbcf453465d8a572f33157766bb0e815cce7c8a2aa8a44422d34a365 -CompilerSupportLibraries.v0.5.0+0.i686-linux-gnu-libgfortran3.tar.gz/md5/fd4035aef1c83be0b865d70aa35e770b -CompilerSupportLibraries.v0.5.0+0.i686-linux-gnu-libgfortran3.tar.gz/sha512/a72047e7071838899d75896b4dcbdc102bca884507f4758b4e0dd62f50c9ce584f2b2b86d8b67dfc4fce9864faf9723056820e464bbab1a6173be47ad941d6da -CompilerSupportLibraries.v0.5.0+0.i686-linux-gnu-libgfortran4.tar.gz/md5/89715bfa0e69528d4d294ed449ef0e09 -CompilerSupportLibraries.v0.5.0+0.i686-linux-gnu-libgfortran4.tar.gz/sha512/6eb7947c72ec32d189221de42d5a76423a1fb5745db0812d88afe7f961d8f42669c7cf487235c1dcc81fbe73106b785c906bd6741e98f60e9931f4083be0e9ce -CompilerSupportLibraries.v0.5.0+0.i686-linux-gnu-libgfortran5.tar.gz/md5/5c1c73dc72029781847f74bcb1189c4b -CompilerSupportLibraries.v0.5.0+0.i686-linux-gnu-libgfortran5.tar.gz/sha512/642d35ed41a65c7a2d7f4f127f936d3cb1665c207aa5feef25cce09cc11e733d7ec129673fea873403567c35cf16122ed1635c303ba13bb3349be44585f3ca82 -CompilerSupportLibraries.v0.5.0+0.i686-linux-musl-libgfortran3.tar.gz/md5/f91c962e7bc3ffb825c7e5fb1e099ba6 -CompilerSupportLibraries.v0.5.0+0.i686-linux-musl-libgfortran3.tar.gz/sha512/f89df221ff80bcbb1e6edc2f9cc28dc138d7d6ae99ac018a3cdc9a09ba637f1a9938b1f0876086f4f822fb911853286dd4f1776d603a403190bee052431ae572 -CompilerSupportLibraries.v0.5.0+0.i686-linux-musl-libgfortran4.tar.gz/md5/d2a81da3371a638f76087629ae0a6507 -CompilerSupportLibraries.v0.5.0+0.i686-linux-musl-libgfortran4.tar.gz/sha512/67941af15a0f032a853cdea180e4f87249bed2dfd09ade6fca9760f5a44b26fc94a0d6932803edbd27b75aa8d26e64c377af2d64ddcba3206562be1427a64c80 -CompilerSupportLibraries.v0.5.0+0.i686-linux-musl-libgfortran5.tar.gz/md5/cec9f3b9d4924a49a34c632efd167752 -CompilerSupportLibraries.v0.5.0+0.i686-linux-musl-libgfortran5.tar.gz/sha512/9320eee2b6dbadd4e0ed3f8763d58854eb179b1d1661c8f1dba75c22af2330812040507944b0ab20b7a7cb233c9953a1d3a4b27937e7b7a858aed2255ad0fbbc -CompilerSupportLibraries.v0.5.0+0.i686-w64-mingw32-libgfortran3.tar.gz/md5/c36411b24c8bec4805230bd4fe0f2391 -CompilerSupportLibraries.v0.5.0+0.i686-w64-mingw32-libgfortran3.tar.gz/sha512/839b447efa46caffa699258ec8ae5e0a55d7f98a7fc037b48e6a6c29193e3d8bf48397575cc518716f41e2e9344daa670693df605a1b9d4a23d3f454ec5ab399 -CompilerSupportLibraries.v0.5.0+0.i686-w64-mingw32-libgfortran4.tar.gz/md5/d2e392edff3525afff6734fdf47c9ab1 -CompilerSupportLibraries.v0.5.0+0.i686-w64-mingw32-libgfortran4.tar.gz/sha512/1816c7ed409acc1435c7fcfd550b7664a08b31ecf433a906d8903a60ed458dab0fa712bd0d1590a0dc8506763a617446ba402efc78a2c010562c45e8eca66a88 -CompilerSupportLibraries.v0.5.0+0.i686-w64-mingw32-libgfortran5.tar.gz/md5/2cfeb5cd0a7e2400c9be3e846a1875d2 -CompilerSupportLibraries.v0.5.0+0.i686-w64-mingw32-libgfortran5.tar.gz/sha512/ca620dd8542ffe9a177b0f95712e77e59b0fc1044e0186dd7468a86aba4d2b92931a1d6f980e75cceb26c6c5f9dab427f4ce32e0f77998b9a827b3ce9151041c -CompilerSupportLibraries.v0.5.0+0.powerpc64le-linux-gnu-libgfortran3.tar.gz/md5/8ba0e4070358839909934d8a1bc9e0bf -CompilerSupportLibraries.v0.5.0+0.powerpc64le-linux-gnu-libgfortran3.tar.gz/sha512/8750769ca321f863fbb354f6e4e76b1241f7e24e5f4ea14ea511486dc5bc4fe8274740f1500149c5ac85a8214a0193c9a09332f35eb47e6222bef9070eecc6c8 -CompilerSupportLibraries.v0.5.0+0.powerpc64le-linux-gnu-libgfortran4.tar.gz/md5/50554a092af3a4a651b53e3ce3cf8a2d -CompilerSupportLibraries.v0.5.0+0.powerpc64le-linux-gnu-libgfortran4.tar.gz/sha512/53ec765d4de3b0bae9727b3b2a27437b184f2072aecda5d0b22d648a95fbba777bb89da823bc851d7242cd3f8c212e3fdaea8e5af11db21c578c2e12db51991d -CompilerSupportLibraries.v0.5.0+0.powerpc64le-linux-gnu-libgfortran5.tar.gz/md5/b09a5913b537b26aa7f8996b1877c748 -CompilerSupportLibraries.v0.5.0+0.powerpc64le-linux-gnu-libgfortran5.tar.gz/sha512/b68020c1b1acf4a1c51822bccc1eb67574ceffae3c133e7efe22ec0cc3a674a7c056c01be02c1c681f469fe1443d76baf4b0e305bec8181e57c3ce5a446a5c22 -CompilerSupportLibraries.v0.5.0+0.x86_64-apple-darwin-libgfortran3.tar.gz/md5/1e4c5d2084f76eacb4419214668c6594 -CompilerSupportLibraries.v0.5.0+0.x86_64-apple-darwin-libgfortran3.tar.gz/sha512/696155b560bfaf592bf7024ba0e6f084382dd269cdd25416fa8840387c101132901e94709c8d0534f038666a6f6849c3d55e8bed4223b5be499e099b49610e77 -CompilerSupportLibraries.v0.5.0+0.x86_64-apple-darwin-libgfortran4.tar.gz/md5/63b386e59f3732d03459c59000fc1382 -CompilerSupportLibraries.v0.5.0+0.x86_64-apple-darwin-libgfortran4.tar.gz/sha512/f6c7e0611df7fd86cc9ca63b380e112561d10b489bc8fbfe911c441ef5e87776761d3c161ff5f6aade479f7e96456084c6939d7eff175ced4f42b3b9ee29426a -CompilerSupportLibraries.v0.5.0+0.x86_64-apple-darwin-libgfortran5.tar.gz/md5/07e22a4b58aaaf145e52b36602c5b08d -CompilerSupportLibraries.v0.5.0+0.x86_64-apple-darwin-libgfortran5.tar.gz/sha512/8a047b0098e8504e2dde0113170416686bc70f9d685fcb19bf3eb76afe30dc16a3b0d2023eb704c25025bbef87e99603dbd2a2708b1a3df908747b06cbfc92ee -CompilerSupportLibraries.v0.5.0+0.x86_64-linux-gnu-libgfortran3.tar.gz/md5/23048b3be33f184ffc9be42ca914aa3a -CompilerSupportLibraries.v0.5.0+0.x86_64-linux-gnu-libgfortran3.tar.gz/sha512/4573b21e34f4d8127a86c18f95065039da92eeb9ade4058bd8459034bb4a003ceefe29e865089126fdc36cffd95a9c12bcb72ed74bff5987a9d1f4b300ecfe45 -CompilerSupportLibraries.v0.5.0+0.x86_64-linux-gnu-libgfortran4.tar.gz/md5/3314ec0668abf069c900558de0690b65 -CompilerSupportLibraries.v0.5.0+0.x86_64-linux-gnu-libgfortran4.tar.gz/sha512/d012c4674401773000f0de831cb8b4b6c454d0ab68d51fbbe970504e76c693211086a24a7df34de2390eaeb438ab23f63c68b480a408ab2136f442aba5094bd7 -CompilerSupportLibraries.v0.5.0+0.x86_64-linux-gnu-libgfortran5.tar.gz/md5/e7768c00909613b8f29f6a5860ff4247 -CompilerSupportLibraries.v0.5.0+0.x86_64-linux-gnu-libgfortran5.tar.gz/sha512/43c29456a0fc74c4fda42d088903651c6bbac6b842f2aa600e3019b391b04158ee97f884e6962bd9e7a9cf337dbb1cdb2151d103e1dee5214ba798b167b1ed32 -CompilerSupportLibraries.v0.5.0+0.x86_64-linux-musl-libgfortran3.tar.gz/md5/b2a30e92ba8e40ef070e3ec7c16b97f0 -CompilerSupportLibraries.v0.5.0+0.x86_64-linux-musl-libgfortran3.tar.gz/sha512/64a4029dd1e84922728b2c93a455d7d6b262c979dddf59301ff96e9c28980fbd9c1db57e81afaece96ccb51b9751e5a0180b84e412427430487280c56d8da266 -CompilerSupportLibraries.v0.5.0+0.x86_64-linux-musl-libgfortran4.tar.gz/md5/b0610d32a80b3f87baebf0250b0f92d6 -CompilerSupportLibraries.v0.5.0+0.x86_64-linux-musl-libgfortran4.tar.gz/sha512/3b7098fbb82e4a7a903b82f942303b248e0e35be13a47e4839a036085c4a33925f1f78fe941b852331cc52de80f32bcdb9a64ccff0386e1070a6ca4600c08eb8 -CompilerSupportLibraries.v0.5.0+0.x86_64-linux-musl-libgfortran5.tar.gz/md5/3f905dd4e8b3cfd2cc3f8efcaa50a407 -CompilerSupportLibraries.v0.5.0+0.x86_64-linux-musl-libgfortran5.tar.gz/sha512/22af14d245e3c062131dd274afa6d9c7cde9a11ee2455e27ae2f7725a025fc2cd6cdb3a1a3c899988c6c3412a714c1f0763f4e08924726212405938c3cf66da5 -CompilerSupportLibraries.v0.5.0+0.x86_64-unknown-freebsd-libgfortran3.tar.gz/md5/2c56a22c935dda76831f36c713cca099 -CompilerSupportLibraries.v0.5.0+0.x86_64-unknown-freebsd-libgfortran3.tar.gz/sha512/6bd9bd6ec8b6b18013b3c6de344de134835c9281d39bc5e6e31928970c60b584fa625df18efbce3ea571dee53011dec73e9aae9159e812f219692fbb4dd86a2d -CompilerSupportLibraries.v0.5.0+0.x86_64-unknown-freebsd-libgfortran4.tar.gz/md5/e483c3e85b4d4b2685ee4e8f09951ac1 -CompilerSupportLibraries.v0.5.0+0.x86_64-unknown-freebsd-libgfortran4.tar.gz/sha512/47c2f305237ccd55ed2ba445cbcd599c23f9c1392388017506f9d61a4dc8fec4ba4136be81a0e82de4f161f6788c4a62acc9d71efe6cf90b766e5339950ed337 -CompilerSupportLibraries.v0.5.0+0.x86_64-unknown-freebsd-libgfortran5.tar.gz/md5/41c25d9cf7545721b8d4dd2386e95ead -CompilerSupportLibraries.v0.5.0+0.x86_64-unknown-freebsd-libgfortran5.tar.gz/sha512/173570bbf4eb60d678472058ec2c18732cd27ad2911457c83f47a1d97c1c0028d91005cf56539e51d4a04178544ac0bba47ea27e74b6b4e8d3310551ad3167fe -CompilerSupportLibraries.v0.5.0+0.x86_64-w64-mingw32-libgfortran3.tar.gz/md5/f124c93580a038ce806f479568b46597 -CompilerSupportLibraries.v0.5.0+0.x86_64-w64-mingw32-libgfortran3.tar.gz/sha512/c313390dbcffaea6cb5202645b5304134a1ce6aac5a3835696f45316c8170b237c04f13166694eee0f31903ac1e5c3cd73ad8974ba19b44289da3504d3436f8c -CompilerSupportLibraries.v0.5.0+0.x86_64-w64-mingw32-libgfortran4.tar.gz/md5/050fe7a6bdf980c198f4c201629d15e0 -CompilerSupportLibraries.v0.5.0+0.x86_64-w64-mingw32-libgfortran4.tar.gz/sha512/211e435f5e2b7209aedaf4a81b5e0d5e615b9144de248c06e43dc61b31890dbde80d718e74454b489bd1f77476d34bd01d3f9a25355bc50fca0dc07df0264cad -CompilerSupportLibraries.v0.5.0+0.x86_64-w64-mingw32-libgfortran5.tar.gz/md5/3566d0f714c1503b92160b486a4eaa4a -CompilerSupportLibraries.v0.5.0+0.x86_64-w64-mingw32-libgfortran5.tar.gz/sha512/b2f29c1c6dc35e1002021f8f15a20a72a57c346b33a6d045ff7a261e88767738a4da1dd88aa71a20514bdf6376099979c9d938173fa3ae28641c40372c94db60 +CompilerSupportLibraries.v0.5.2+0.aarch64-apple-darwin-libgfortran5.tar.gz/md5/e0651fbefd39d405ec97d7530f2887d7 +CompilerSupportLibraries.v0.5.2+0.aarch64-apple-darwin-libgfortran5.tar.gz/sha512/0a067b7e37d98a4c96dd1400b8c1a07c82cc223d11a93a0ee2455c3b55b394eee0cb251e26206495453f2cf8866822fb586ffe105f44e3380fa949adffe8b83c +CompilerSupportLibraries.v0.5.2+0.aarch64-linux-gnu-libgfortran3.tar.gz/md5/1f4a5e98cd88a08029326ca5e9d47e9c +CompilerSupportLibraries.v0.5.2+0.aarch64-linux-gnu-libgfortran3.tar.gz/sha512/696f359746de592d4e30dc9ad19d5e07ebc1e6635e1f082e249747c42338ef04ce885fee5ad5915ec39fa2866af4265bb6ef580c75874c091a15b64d02626123 +CompilerSupportLibraries.v0.5.2+0.aarch64-linux-gnu-libgfortran4.tar.gz/md5/8285fd34164fac0410fcec6bb9d8b8e4 +CompilerSupportLibraries.v0.5.2+0.aarch64-linux-gnu-libgfortran4.tar.gz/sha512/df0869d357326c803d8ff33c9734f01457d877e80c4af33745d4ca016144eb0c52fba7aad7e1098eecde3fc4cf41ed971638b4b6f901c7306a2072e8c14c3513 +CompilerSupportLibraries.v0.5.2+0.aarch64-linux-gnu-libgfortran5.tar.gz/md5/82add6093bda667442236c04d84b6934 +CompilerSupportLibraries.v0.5.2+0.aarch64-linux-gnu-libgfortran5.tar.gz/sha512/81538d75950cdf931f9aaa932d1f9cf40998bc256924c3231e984179f6a5c3eca0f7e1ba315b21f2add3bf9376e3a45ee59ccd8d9f6d765105e05da25bf65cfc +CompilerSupportLibraries.v0.5.2+0.aarch64-linux-musl-libgfortran3.tar.gz/md5/ee0d6a9f0a1372e36a02a95b6c07aefc +CompilerSupportLibraries.v0.5.2+0.aarch64-linux-musl-libgfortran3.tar.gz/sha512/f248e57249af88520f9c7ac32dba45ca03e5904606b4edb682ea514c31a9a775198d02f0892e79124326e184d7906b7a13b0e4f3e7721352b8105cdfa72f89ed +CompilerSupportLibraries.v0.5.2+0.aarch64-linux-musl-libgfortran4.tar.gz/md5/dddc8f7a9be9f07e9738e2a027fe8a0c +CompilerSupportLibraries.v0.5.2+0.aarch64-linux-musl-libgfortran4.tar.gz/sha512/36f9b94f470d451b9c3c2429026292463434427625563240467f50374624a69fbca7ddcb0678937a58d22d32a8157571d3e201c47cc9a2484d1d75d4c0f77ebc +CompilerSupportLibraries.v0.5.2+0.aarch64-linux-musl-libgfortran5.tar.gz/md5/12b7eb088023eaf9583ffa6f9f0e18ac +CompilerSupportLibraries.v0.5.2+0.aarch64-linux-musl-libgfortran5.tar.gz/sha512/a5f5a6053e63ea1fb0185a0c3a7752a938373da847dffb872c1227ed3a0a80f2de1e4394baaaeeb8e0d8f2a4da123433896742cfdca6f94343bd4d0ab3578c65 +CompilerSupportLibraries.v0.5.2+0.armv6l-linux-gnueabihf-libgfortran3.tar.gz/md5/e5e6918571981e4cfa5a2951e59f2df7 +CompilerSupportLibraries.v0.5.2+0.armv6l-linux-gnueabihf-libgfortran3.tar.gz/sha512/5d7b0f4f55b6726ae7317edb170cafb6a2c4563b0f4a90c619da95c120edd8fdce118bbd1e7168110f75cc899b857472fd524a396deb6d9f2552f53c861faeb7 +CompilerSupportLibraries.v0.5.2+0.armv6l-linux-gnueabihf-libgfortran4.tar.gz/md5/7ae11706e9c6c043ad771f2700d06591 +CompilerSupportLibraries.v0.5.2+0.armv6l-linux-gnueabihf-libgfortran4.tar.gz/sha512/4f2f01aed00a58f4393cfd4608df1a6df6c9bff6e352a02a2b9af13f14a4436611769d64d082d3b151ba23d3d905ae2700bf469b9858249757ad7b5aae716d6a +CompilerSupportLibraries.v0.5.2+0.armv6l-linux-gnueabihf-libgfortran5.tar.gz/md5/e922dad7dad1d5f80cc154a6ddb6de35 +CompilerSupportLibraries.v0.5.2+0.armv6l-linux-gnueabihf-libgfortran5.tar.gz/sha512/3fabbcedbbc4abfe1e0c01c387bbe2537105937674877122b5b66d6015944a58f547106da1e185c1434de0c1883d356f8dc52968f075a00c6a8a52edaaf88957 +CompilerSupportLibraries.v0.5.2+0.armv6l-linux-musleabihf-libgfortran3.tar.gz/md5/53741f61d806efe045a5abe0e748aa36 +CompilerSupportLibraries.v0.5.2+0.armv6l-linux-musleabihf-libgfortran3.tar.gz/sha512/b975a8fdfb736ef2b1aede2c89e390df261bfe8aaf8ffdb37887add09263d95f46642c3898ac19ec6098cdfdfc7f0726436dc273e9f70f10fe1abf4ea945277a +CompilerSupportLibraries.v0.5.2+0.armv6l-linux-musleabihf-libgfortran4.tar.gz/md5/9687cf768c6c2879261e385c44ba490c +CompilerSupportLibraries.v0.5.2+0.armv6l-linux-musleabihf-libgfortran4.tar.gz/sha512/02f9accf8273597f6889677de64255e4e399d67377b5363ed31dea7e2118cc24d3b7fad7c0632aea79dee44250b1ff74bf2fa22e4f3e7755de65871854112c14 +CompilerSupportLibraries.v0.5.2+0.armv6l-linux-musleabihf-libgfortran5.tar.gz/md5/b62a81b9f43903b3de6fa1c78c03b89f +CompilerSupportLibraries.v0.5.2+0.armv6l-linux-musleabihf-libgfortran5.tar.gz/sha512/d44eecb30ccf19bc8dca41c738dbedd2bd2cb6e379a3ab181c955cb9cdf9bae8efeaf7a90c85dc7434520ead7e910d38e92b448cff7aecaef0902684e9b06c9f +CompilerSupportLibraries.v0.5.2+0.armv7l-linux-gnueabihf-libgfortran3.tar.gz/md5/e31780333339ac64f54ad434578d6294 +CompilerSupportLibraries.v0.5.2+0.armv7l-linux-gnueabihf-libgfortran3.tar.gz/sha512/9c3b91ed90f3393dfc72e7e2feefa60afe6ad457971950b163ffbecafa41cea43a15cdfadd8f402fd8fb61652c224f5b1a04c432fb0f43593749f51ed1340116 +CompilerSupportLibraries.v0.5.2+0.armv7l-linux-gnueabihf-libgfortran4.tar.gz/md5/0f7bdfb908aa3d721428a1ee8412b594 +CompilerSupportLibraries.v0.5.2+0.armv7l-linux-gnueabihf-libgfortran4.tar.gz/sha512/3199da41c3df3d702a557c8b5e9fdde3a47c12d4c45fb9094fd194cbbe667663334b6cc0a5169fcc755790c4b5fada71c5094dc8d9a7f8b6c836d3f4c4c6e509 +CompilerSupportLibraries.v0.5.2+0.armv7l-linux-gnueabihf-libgfortran5.tar.gz/md5/f455758e436750092ba2df65adcfd380 +CompilerSupportLibraries.v0.5.2+0.armv7l-linux-gnueabihf-libgfortran5.tar.gz/sha512/b5d0dbdff19b5ce076b8ae7b907da25fdbe05eabd47e46987f9987690a3a670d14bd3d2c2343d366ca1ee861b85fcbaccc1460ba3a73571686ef9e4330427b65 +CompilerSupportLibraries.v0.5.2+0.armv7l-linux-musleabihf-libgfortran3.tar.gz/md5/4cf3790d881b829b4b8da882987d5a40 +CompilerSupportLibraries.v0.5.2+0.armv7l-linux-musleabihf-libgfortran3.tar.gz/sha512/ef5810243af32135da0cb7d08ae35ff8a2cce50c05200450154aa860c181719844466b787faae551aa71bd94e721f2d7d17ab14a049d0558666037862aff2f6a +CompilerSupportLibraries.v0.5.2+0.armv7l-linux-musleabihf-libgfortran4.tar.gz/md5/a49e1fa6e040ac86ddd85a3188f83a76 +CompilerSupportLibraries.v0.5.2+0.armv7l-linux-musleabihf-libgfortran4.tar.gz/sha512/cb0292651392a14f952181eb7a4a0ea6359632e96b017169cf4f1792f44f2846b5d6b2b5d334dee490262dd1c2d421de49d1f4a919402392f77fdaf60c1d19a3 +CompilerSupportLibraries.v0.5.2+0.armv7l-linux-musleabihf-libgfortran5.tar.gz/md5/3f64969e0e70dc8644fe09637dd1cbe7 +CompilerSupportLibraries.v0.5.2+0.armv7l-linux-musleabihf-libgfortran5.tar.gz/sha512/0a71f8b731911019666bdc82f42e306ff1801321362ce6fe58988c9a1b110cd032a01c11fd0f9a6a3fbf6c6545f3287e363f5b3c40ef2eab0659638c38687196 +CompilerSupportLibraries.v0.5.2+0.i686-linux-gnu-libgfortran3.tar.gz/md5/28f58931f66a3405fc4c99ce40724ece +CompilerSupportLibraries.v0.5.2+0.i686-linux-gnu-libgfortran3.tar.gz/sha512/d5290079264cfc6f716dcc9171f8412369e685c7ba0b9e82ae3d764de41671fbb4a24fdf7ebae9a9b913393837c2e41951326dbf3e870340fba7121709ebba8b +CompilerSupportLibraries.v0.5.2+0.i686-linux-gnu-libgfortran4.tar.gz/md5/f98763aae801cc7d88124bea422f13ca +CompilerSupportLibraries.v0.5.2+0.i686-linux-gnu-libgfortran4.tar.gz/sha512/da2095a462637ffcd0825949f4bcc86be9484c9e009648dc3c2e22e2fa19c65124e5e45f2694e85616df49b1181e2f4d2b886d3b83401c09ca58207db461ea23 +CompilerSupportLibraries.v0.5.2+0.i686-linux-gnu-libgfortran5.tar.gz/md5/1bfee57db4f2bdd788e59e34d0bb4506 +CompilerSupportLibraries.v0.5.2+0.i686-linux-gnu-libgfortran5.tar.gz/sha512/8f4814d97d6cd6c1f0c1d23fce875c40b6df7de7a8dc66e66681ba3c533120cb14d9d018808ff4e33dec53bb8958fbcedc9be6ac70817839ff89a0db5c0d18a8 +CompilerSupportLibraries.v0.5.2+0.i686-linux-musl-libgfortran3.tar.gz/md5/5da7af0483ffde929c58f3ae411f6489 +CompilerSupportLibraries.v0.5.2+0.i686-linux-musl-libgfortran3.tar.gz/sha512/97e56fe4fe0e10fa0d57ec10882a62d290829940049ffce7a8d81a843b91c7844e53d737bcdbc7a5e8206ca9820a7066fcdd7d0eed1e831d7af96222ccca1224 +CompilerSupportLibraries.v0.5.2+0.i686-linux-musl-libgfortran4.tar.gz/md5/a0b5cf513f2f02107c8887ea5e30cdda +CompilerSupportLibraries.v0.5.2+0.i686-linux-musl-libgfortran4.tar.gz/sha512/aeeacfb58094751fe5cec87825ebb02a22c58d3e7300b6ca6066eb717e28ebecff230838c32935ac11376a6efdd5a0c44fe0c8e7d5b9a1f0165171c2b67a2d8b +CompilerSupportLibraries.v0.5.2+0.i686-linux-musl-libgfortran5.tar.gz/md5/569ef42292d8cfd157026b434e93fe4d +CompilerSupportLibraries.v0.5.2+0.i686-linux-musl-libgfortran5.tar.gz/sha512/daf543fbe7e80fd63220f7c08e0d6b51d45ce9e0af592a591eecadcaac9b859ce596df2bf8fcb3fb72fb799f869d0caac28acb5d26b3c3aed6dc80245b90dcce +CompilerSupportLibraries.v0.5.2+0.i686-w64-mingw32-libgfortran3.tar.gz/md5/f4e0f3d40f7f77d32f26424dedff850f +CompilerSupportLibraries.v0.5.2+0.i686-w64-mingw32-libgfortran3.tar.gz/sha512/57e35c39c4c93919cdbbe33891b5938918d33840ad33ed51a010f9deab791d60fa2d030d3e14df6e445e0607dc9280b07ca287a3273630bf7e245d6ab8069cbd +CompilerSupportLibraries.v0.5.2+0.i686-w64-mingw32-libgfortran4.tar.gz/md5/d366731c11314cb908fca2032e7fefca +CompilerSupportLibraries.v0.5.2+0.i686-w64-mingw32-libgfortran4.tar.gz/sha512/a7e087e718f9d8cb4957b8bf3a4554faae97510b25d88a3e9ae4241cb69efa5b520bd9424a0072e7d712c9435e6900690c56004a716a716838367e91fe20e11d +CompilerSupportLibraries.v0.5.2+0.i686-w64-mingw32-libgfortran5.tar.gz/md5/eff855bb45f038c9d74c67ae2eed5641 +CompilerSupportLibraries.v0.5.2+0.i686-w64-mingw32-libgfortran5.tar.gz/sha512/e674d60247086bb8029270406d246a4857e668442a77299a431ec837446387bd1ed2de5e0f9f6985cc6e5d15b6692f40b18e0016e7c9d4e95a3770dffc19b44d +CompilerSupportLibraries.v0.5.2+0.powerpc64le-linux-gnu-libgfortran3.tar.gz/md5/0bfe78d226b3d89a83b54c6ff39239e1 +CompilerSupportLibraries.v0.5.2+0.powerpc64le-linux-gnu-libgfortran3.tar.gz/sha512/fed14514c9603a1e4772d2fd5f4a48da751c10e34b6fba5e0c35ff40b8ed165af6daebc051fa86751bdffb8f820ac779215dc3b38c4ff5c1624214b61d7ad1b0 +CompilerSupportLibraries.v0.5.2+0.powerpc64le-linux-gnu-libgfortran4.tar.gz/md5/d5219b60117555a3ccd41ab406d485f4 +CompilerSupportLibraries.v0.5.2+0.powerpc64le-linux-gnu-libgfortran4.tar.gz/sha512/9268d7c2c6ef649dc753757f9afc7ac1382e521d02c58a91eead9873f2a80f215f3b67f9a33abad53c8bca18c19ae3e63804e01e3109c939d33555c7ec8c5b1a +CompilerSupportLibraries.v0.5.2+0.powerpc64le-linux-gnu-libgfortran5.tar.gz/md5/1f620c9a049e00b8b11c3970a23f2761 +CompilerSupportLibraries.v0.5.2+0.powerpc64le-linux-gnu-libgfortran5.tar.gz/sha512/6ac900dfac9268334c9b54badbfbec323151353e8d87d3199f875a505febf863766ded0c52bce2939e5975fa6e35a28cc16c88e7c1cce37d65725fe275813606 +CompilerSupportLibraries.v0.5.2+0.x86_64-apple-darwin-libgfortran3.tar.gz/md5/c21c35b00ed7ad0171d63006f1a4170d +CompilerSupportLibraries.v0.5.2+0.x86_64-apple-darwin-libgfortran3.tar.gz/sha512/f993a616a75b1f5ee140ed47b6e4aa981cffbbffd795fc0cf9df9397a6366a4507a158530e961c398bab656e7d51a27be026088678e0c19485ef0bad136bb69a +CompilerSupportLibraries.v0.5.2+0.x86_64-apple-darwin-libgfortran4.tar.gz/md5/f0cd5c8631256f3b903e95ad3623d702 +CompilerSupportLibraries.v0.5.2+0.x86_64-apple-darwin-libgfortran4.tar.gz/sha512/81de3f699169254fa83a3ab8b6063ddfd300065edf90f15239b0a304f3feea9534acba7d982058a7712ce94dcdb1ae036502f276813a96f8254e323787556d63 +CompilerSupportLibraries.v0.5.2+0.x86_64-apple-darwin-libgfortran5.tar.gz/md5/6030c114c1250e99958a0727da9d6daf +CompilerSupportLibraries.v0.5.2+0.x86_64-apple-darwin-libgfortran5.tar.gz/sha512/1d4be1c0718aeab056368653b7f34bd5ac3c85edb9fbdc2752b8c4877fcf5d080774506519cf285954485d806bccc18323f6c45f069db8bd314d064a2cc1ed66 +CompilerSupportLibraries.v0.5.2+0.x86_64-linux-gnu-libgfortran3.tar.gz/md5/b45ac0c04357de9d013df598dd13f3bf +CompilerSupportLibraries.v0.5.2+0.x86_64-linux-gnu-libgfortran3.tar.gz/sha512/42174d05c7165f87693efa09facc9405c9d6eab490c4b5fc74ba02e1e2e871799a24dcb7496e0693f30f9c3fd7e81020b77a3dd946832288769063f6d2a31aba +CompilerSupportLibraries.v0.5.2+0.x86_64-linux-gnu-libgfortran4.tar.gz/md5/761998b08e4b460cec95468adb850c31 +CompilerSupportLibraries.v0.5.2+0.x86_64-linux-gnu-libgfortran4.tar.gz/sha512/32853dcb3202e735325e1e0e3d88e2e446d7c88d45bc462d4e91f7d57dfd78b0f3381302e72163fafdb1c2cef53d4822e1c52289081e06b7b74d67e2ed0d34c2 +CompilerSupportLibraries.v0.5.2+0.x86_64-linux-gnu-libgfortran5.tar.gz/md5/dfd50d071702f903213ea0c6a42ad81b +CompilerSupportLibraries.v0.5.2+0.x86_64-linux-gnu-libgfortran5.tar.gz/sha512/3d6ecca7689bcb1925801d26a328790228c564bb731f6fa25d88763eeb22cccc4409dd6376c7b574ec242fbf85e41fd82d038a2650f8d33bb850b9a9a9f9a722 +CompilerSupportLibraries.v0.5.2+0.x86_64-linux-musl-libgfortran3.tar.gz/md5/0b374bc55dd0d5f4cf34a12d4901c022 +CompilerSupportLibraries.v0.5.2+0.x86_64-linux-musl-libgfortran3.tar.gz/sha512/10db23cc1d1367f40fed6c6cfc232fdc49f55e666d3623faa1af40dd781ea7a5d37b6b5a39524f0fc57d6d49947f429389bbf7075f10163090d7ea48903e688a +CompilerSupportLibraries.v0.5.2+0.x86_64-linux-musl-libgfortran4.tar.gz/md5/1e28cdc7937a500b081a1f4d340190f2 +CompilerSupportLibraries.v0.5.2+0.x86_64-linux-musl-libgfortran4.tar.gz/sha512/0b635b8f594739453033fd1dc5496976a8fff314dd078e2d8248d3c2136abaaa610ebc45252a81d16db9d91a0ec20a552f1bcb65ed3b50a627e40168e7f100e0 +CompilerSupportLibraries.v0.5.2+0.x86_64-linux-musl-libgfortran5.tar.gz/md5/f6fcf32044f69d8305a718eeb7651614 +CompilerSupportLibraries.v0.5.2+0.x86_64-linux-musl-libgfortran5.tar.gz/sha512/5940a145a3203d5a4a9b7cd9aab45b8bcff08a43a69a8fea67a9e18535625c8ecc051ba344421253b2f96eaa1a007d42555897a8f8aa0e8bd5dbf1ddbd38f197 +CompilerSupportLibraries.v0.5.2+0.x86_64-unknown-freebsd-libgfortran3.tar.gz/md5/eb46728ef7d3ce955d5a497a556138c2 +CompilerSupportLibraries.v0.5.2+0.x86_64-unknown-freebsd-libgfortran3.tar.gz/sha512/922d3a85059e7cedc6e0e52687cd6f22cb708677a65fcab86f7571737d8f17455f15b3f1af7442ee5fd04a437f226d4eee374d0f353a10f8f7a87160d7a2351d +CompilerSupportLibraries.v0.5.2+0.x86_64-unknown-freebsd-libgfortran4.tar.gz/md5/fc1f4fc44c08f0c3040b976558a35e3e +CompilerSupportLibraries.v0.5.2+0.x86_64-unknown-freebsd-libgfortran4.tar.gz/sha512/5406251fe1d1d1901ac4e6af3b8e9394fcaee2fa6a4f3d2817161a1626bc6b45d7b184f9bdd3d2e6571640f40b4e06c61f321358ad8fe484871ab9b878801a95 +CompilerSupportLibraries.v0.5.2+0.x86_64-unknown-freebsd-libgfortran5.tar.gz/md5/e1b52fdb233c9667610867e278e7719a +CompilerSupportLibraries.v0.5.2+0.x86_64-unknown-freebsd-libgfortran5.tar.gz/sha512/efadc4efc419808cb289c8c8f52664a72f2646bad2e8e02533456cf9afd613d4cbacd121da786316206df8f65b5264498f25adb04f7673121b2a58a20c4a75b9 +CompilerSupportLibraries.v0.5.2+0.x86_64-w64-mingw32-libgfortran3.tar.gz/md5/a449351de41a3140534d278aacedc54e +CompilerSupportLibraries.v0.5.2+0.x86_64-w64-mingw32-libgfortran3.tar.gz/sha512/db5bfbd161eba076598465cfee277418c6e9f4f0f7c4672a437c68ceff374f600917fdcaaa9dfdb945103d2b5c9786663e8e9403f6fdc796cda7c529dadf28ba +CompilerSupportLibraries.v0.5.2+0.x86_64-w64-mingw32-libgfortran4.tar.gz/md5/facd6a008270b85d08ca835556921127 +CompilerSupportLibraries.v0.5.2+0.x86_64-w64-mingw32-libgfortran4.tar.gz/sha512/236438e05eb3f50063aea90522e61f10a03c474f3c26117c071bf94d4ca24fae56e09a565cbf00dc5d1eabefec804fa5503ecbcc324b5da00a65b5471fccfadf +CompilerSupportLibraries.v0.5.2+0.x86_64-w64-mingw32-libgfortran5.tar.gz/md5/cd294be65ddd327d6c0feeca8b13f922 +CompilerSupportLibraries.v0.5.2+0.x86_64-w64-mingw32-libgfortran5.tar.gz/sha512/73dc99009d25fa0ebafa77d7c5747d21a6e0778a6266a2408df885d9553e4b8029c104e1fe174526d9261252bb564128ae7cf9058268475d168c79d19ee4f0c0 diff --git a/stdlib/CompilerSupportLibraries_jll/Project.toml b/stdlib/CompilerSupportLibraries_jll/Project.toml index 15ca525723c07..877a1ab5b005c 100644 --- a/stdlib/CompilerSupportLibraries_jll/Project.toml +++ b/stdlib/CompilerSupportLibraries_jll/Project.toml @@ -4,7 +4,7 @@ uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" # NOTE: When updating this, also make sure to update the value # `CSL_NEXT_GLIBCXX_VERSION` in `deps/csl.mk`, to properly disable # automatic usage of BB-built CSLs on extremely up-to-date systems! -version = "0.5.0+0" +version = "0.5.2+0" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" diff --git a/stdlib/CompilerSupportLibraries_jll/src/CompilerSupportLibraries_jll.jl b/stdlib/CompilerSupportLibraries_jll/src/CompilerSupportLibraries_jll.jl index af8a679d87e10..1b2c0cd41cbe2 100644 --- a/stdlib/CompilerSupportLibraries_jll/src/CompilerSupportLibraries_jll.jl +++ b/stdlib/CompilerSupportLibraries_jll/src/CompilerSupportLibraries_jll.jl @@ -33,7 +33,7 @@ if Sys.iswindows() const libgomp = "libgomp-1.dll" elseif Sys.isapple() if arch(HostPlatform()) == "aarch64" - const libgcc_s = "@rpath/libgcc_s.2.dylib" + const libgcc_s = "@rpath/libgcc_s.1.1.dylib" else const libgcc_s = "@rpath/libgcc_s.1.dylib" end From abf0a9a0e2ed0942139b985d40557c6188016eb9 Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Wed, 9 Mar 2022 08:22:11 +0100 Subject: [PATCH 37/46] export CanonicalIndexError (#44524) (cherry picked from commit cd704d28eba856cb40c218746bc4a9f00fb2464e) --- base/exports.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/base/exports.jl b/base/exports.jl index 2d790f16b7986..dff6b0c9bc208 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -122,6 +122,7 @@ export Cwstring, # Exceptions + CanonicalIndexError, CapturedException, CompositeException, DimensionMismatch, From 9de639a748580cd60bc1383b59f30e249769043d Mon Sep 17 00:00:00 2001 From: Juan Ignacio Polanco Date: Fri, 11 Mar 2022 21:34:33 +0100 Subject: [PATCH 38/46] `range` uses `TwicePrecision` when possible (part 2) (#44528) (cherry picked from commit 45ab66452ef08cfcb62aa091037ce0a78367a762) --- base/twiceprecision.jl | 18 ++++++++++++++--- test/ranges.jl | 46 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 59 insertions(+), 5 deletions(-) diff --git a/base/twiceprecision.jl b/base/twiceprecision.jl index 6d91431e47abb..860f2d23185cc 100644 --- a/base/twiceprecision.jl +++ b/base/twiceprecision.jl @@ -453,8 +453,14 @@ end step(r::StepRangeLen{T,TwicePrecision{T},TwicePrecision{T}}) where {T<:AbstractFloat} = T(r.step) step(r::StepRangeLen{T,TwicePrecision{T},TwicePrecision{T}}) where {T} = T(r.step) -range_start_step_length(a, st::IEEEFloat, len::Integer) = - range_start_step_length(oftype(st, a), st, len) +range_start_step_length(a::Real, st::IEEEFloat, len::Integer) = + range_start_step_length(promote(a, st)..., len) + +range_start_step_length(a::IEEEFloat, st::Real, len::Integer) = + range_start_step_length(promote(a, st)..., len) + +range_start_step_length(a::IEEEFloat, st::IEEEFloat, len::Integer) = + range_start_step_length(promote(a, st)..., len) function range_start_step_length(a::T, st::T, len::Integer) where T<:IEEEFloat len = len + 0 # promote with Int @@ -474,7 +480,13 @@ function range_start_step_length(a::T, st::T, len::Integer) where T<:IEEEFloat steprangelen_hp(T, a, st, 0, len, 1) end -function range_step_stop_length(step::IEEEFloat, stop, len::Integer) +range_step_stop_length(step::Real, stop::IEEEFloat, len::Integer) = + range_step_stop_length(promote(step, stop)..., len) + +range_step_stop_length(step::IEEEFloat, stop::Real, len::Integer) = + range_step_stop_length(promote(step, stop)..., len) + +function range_step_stop_length(step::IEEEFloat, stop::IEEEFloat, len::Integer) r = range_start_step_length(stop, negate(step), len) reverse(r) end diff --git a/test/ranges.jl b/test/ranges.jl index 536c1f4710d9d..c448f4b99e201 100644 --- a/test/ranges.jl +++ b/test/ranges.jl @@ -1618,9 +1618,51 @@ end @test x == [0.0, 0.2, 0.4, 0.6, 0.8] end - let x = @inferred range(stop=1, step=0.2, length=5) + let x = @inferred range(0.0, step=2, length=5) @test x isa StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}} - @test x == [0.2, 0.4, 0.6, 0.8, 1.0] + @test x == [0.0, 2.0, 4.0, 6.0, 8.0] + @test x === range(0.0, step=2.0, length=5) + @test x === range(0.0f0, step=2e0, length=5) + @test x === range(0e0, step=2.0f0, length=5) + end + + # start::IEEEFloat and step::Complex + let x = @inferred range(2.0, step=1im, length=3) + @test typeof(x) === StepRangeLen{ComplexF64, Float64, Complex{Int}, Int} + @test x == range(2, step=1im, length=3) # compare with integer range + @test x == 2.0 .+ [0im, 1im, 2im] + end + + # start::Complex and step::IEEEFloat + let x = @inferred range(2im, step=1.0, length=3) + @test typeof(x) === StepRangeLen{ComplexF64, Complex{Int}, Float64, Int} + @test x == range(2im, step=1, length=3) # compare with integer range + end + + # stop::IEEEFloat and step::Complex + let x = @inferred range(stop=2.0, step=1im, length=3) + @test typeof(x) === StepRangeLen{ComplexF64, ComplexF64, Complex{Int}, Int} + @test x == range(stop=2, step=1im, length=3) # compare with integer range + @test x == 2.0 .- [2im, 1im, 0im] + end + + # stop::Complex and step::IEEEFloat + let x = @inferred range(stop=2im, step=1.0, length=3) + @test typeof(x) === StepRangeLen{ComplexF64, ComplexF64, Float64, Int} + @test x == range(stop=2im, step=1, length=3) # compare with integer range + end + + let x = @inferred range(stop=10, step=2.0, length=5) + @test x isa StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}} + @test x === @inferred range(stop=10.0, step=2.0, length=5) + @test x === @inferred range(stop=10f0, step=2.0, length=5) + @test x === @inferred range(stop=10e0, step=2.0f0, length=5) + @test x == [2, 4, 6, 8, 10] + end + + let x = @inferred range(stop=10.0, step=2, length=4) + @test x isa StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}} + @test x == [4.0, 6.0, 8.0, 10.0] end end From 1caaa303b96cd2165b2e4ab62820b76499be91c1 Mon Sep 17 00:00:00 2001 From: Oscar Smith Date: Sat, 12 Mar 2022 03:01:25 -0500 Subject: [PATCH 39/46] fix precision issue in Float64^Float64. (#44529) * improve accuracy for x^-3 (cherry picked from commit 258ddc07d413e4c5889a6594a5b93ac6e1508018) --- base/intfuncs.jl | 1 - base/math.jl | 9 +++--- .../manual/complex-and-rational-numbers.md | 2 +- test/math.jl | 30 +++++++++++++++---- 4 files changed, 30 insertions(+), 12 deletions(-) diff --git a/base/intfuncs.jl b/base/intfuncs.jl index 3c2d9b4beec7b..44c7be0626126 100644 --- a/base/intfuncs.jl +++ b/base/intfuncs.jl @@ -321,7 +321,6 @@ const HWNumber = Union{HWReal, Complex{<:HWReal}, Rational{<:HWReal}} @inline literal_pow(::typeof(^), x::HWNumber, ::Val{3}) = x*x*x @inline literal_pow(::typeof(^), x::HWNumber, ::Val{-1}) = inv(x) @inline literal_pow(::typeof(^), x::HWNumber, ::Val{-2}) = (i=inv(x); i*i) -@inline literal_pow(::typeof(^), x::HWNumber, ::Val{-3}) = (i=inv(x); i*i*i) # don't use the inv(x) transformation here since float^p is slightly more accurate @inline literal_pow(::typeof(^), x::AbstractFloat, ::Val{p}) where {p} = x^p diff --git a/base/math.jl b/base/math.jl index 1fb10467e184f..a8ec2a97f0f61 100644 --- a/base/math.jl +++ b/base/math.jl @@ -1009,8 +1009,8 @@ end !isfinite(x) && return x*(y>0 || isnan(x)) x==0 && return abs(y)*Inf*(!(y>0)) logxhi,logxlo = Base.Math._log_ext(x) - xyhi = logxhi*y - xylo = logxlo*y + xyhi, xylo = two_mul(logxhi,y) + xylo = muladd(logxlo, y, xylo) hi = xyhi+xylo return Base.Math.exp_impl(hi, xylo-(hi-xyhi), Val(:ℯ)) end @@ -1040,6 +1040,7 @@ end @assume_effects :terminates_locally @noinline function pow_body(x::Float64, n::Integer) y = 1.0 xnlo = ynlo = 0.0 + n == 3 && return x*x*x # keep compatibility with literal_pow if n < 0 rx = inv(x) n==-2 && return rx*rx #keep compatability with literal_pow @@ -1047,7 +1048,6 @@ end x = rx n = -n end - n == 3 && return x*x*x # keep compatibility with literal_pow while n > 1 if n&1 > 0 err = muladd(y, xnlo, x*ynlo) @@ -1064,8 +1064,9 @@ end end function ^(x::Float32, n::Integer) - n < 0 && return inv(x)^(-n) + n == -2 && return (i=inv(x); i*i) n == 3 && return x*x*x #keep compatibility with literal_pow + n < 0 && return Float32(Base.power_by_squaring(inv(Float64(x)),-n)) Float32(Base.power_by_squaring(Float64(x),n)) end @inline ^(x::Float16, y::Integer) = Float16(Float32(x) ^ y) diff --git a/doc/src/manual/complex-and-rational-numbers.md b/doc/src/manual/complex-and-rational-numbers.md index 94ad70982bbae..ac48e5b420f5e 100644 --- a/doc/src/manual/complex-and-rational-numbers.md +++ b/doc/src/manual/complex-and-rational-numbers.md @@ -36,7 +36,7 @@ julia> (-1 + 2im)^2 -3 - 4im julia> (-1 + 2im)^2.5 -2.7296244647840084 - 6.960664459571898im +2.729624464784009 - 6.9606644595719im julia> (-1 + 2im)^(1 + 1im) -0.27910381075826657 + 0.08708053414102428im diff --git a/test/math.jl b/test/math.jl index 22bb026ceed0c..e93ad225d3111 100644 --- a/test/math.jl +++ b/test/math.jl @@ -155,12 +155,6 @@ end @test x^y === T(big(x)^big(y)) @test x^1 === x @test x^yi === T(big(x)^yi) - # test (-x)^y for y larger than typemax(Int) - @test T(-1)^floatmax(T) === T(1) - @test prevfloat(T(-1))^floatmax(T) === T(Inf) - @test nextfloat(T(-1))^floatmax(T) === T(0.0) - # test for large negative exponent where error compensation matters - @test 0.9999999955206014^-1.0e8 == 1.565084574870928 @test (-x)^yi == x^yi @test (-x)^(yi+1) == -(x^(yi+1)) @test acos(x) ≈ acos(big(x)) @@ -1323,6 +1317,30 @@ end end end +@testset "pow" begin + for T in (Float16, Float32, Float64) + for x in (0.0, -0.0, 1.0, 10.0, 2.0, Inf, NaN, -Inf, -NaN) + for y in (0.0, -0.0, 1.0, -3.0,-10.0 , Inf, NaN, -Inf, -NaN) + got, expected = T(x)^T(y), T(big(x))^T(y) + @test isnan_type(T, got) && isnan_type(T, expected) || (got === expected) + end + end + for _ in 1:2^16 + x=rand(T)*100; y=rand(T)*200-100 + got, expected = x^y, widen(x)^y + if isfinite(eps(T(expected))) + @test abs(expected-got) <= 1.3*eps(T(expected)) || (x,y) + end + end + # test (-x)^y for y larger than typemax(Int) + @test T(-1)^floatmax(T) === T(1) + @test prevfloat(T(-1))^floatmax(T) === T(Inf) + @test nextfloat(T(-1))^floatmax(T) === T(0.0) + end + # test for large negative exponent where error compensation matters + @test 0.9999999955206014^-1.0e8 == 1.565084574870928 +end + # Test that sqrt behaves correctly and doesn't exhibit fp80 double rounding. # This happened on old glibc versions. # Test case from https://sourceware.org/bugzilla/show_bug.cgi?id=14032. From 9b0333f804bd0ea948b72b1f19354f35f704f858 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Fri, 11 Mar 2022 12:10:29 -0500 Subject: [PATCH 40/46] [LLVM/ABI] Don't pass null pointer to byVal attribute (#44555) (cherry picked from commit f5d15571b3f1745f7783509e336c4d9f7246cdd9) --- src/abi_x86_64.cpp | 1 - src/ccall.cpp | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/abi_x86_64.cpp b/src/abi_x86_64.cpp index 2a06ee6be36a6..43e539b8386ce 100644 --- a/src/abi_x86_64.cpp +++ b/src/abi_x86_64.cpp @@ -202,7 +202,6 @@ bool needPassByRef(jl_datatype_t *dt, AttrBuilder &ab, LLVMContext &ctx, Type *T else if (jl_is_structtype(dt)) { // spill to memory even though we would ordinarily pass // it in registers - Type* Ty = preferred_llvm_type(dt, false, ctx); ab.addByValAttr(Ty); return true; } diff --git a/src/ccall.cpp b/src/ccall.cpp index 1fc6e5d4d3ece..17f75dfefbc2e 100644 --- a/src/ccall.cpp +++ b/src/ccall.cpp @@ -1089,6 +1089,7 @@ std::string generate_func_sig(const char *fname) } // Whether or not LLVM wants us to emit a pointer to the data + assert(t && "LLVM type should not be null"); bool byRef = abi->needPassByRef((jl_datatype_t*)tti, ab, lrt->getContext(), t); if (jl_is_cpointer_type(tti)) { From b2252f449dd90a4fc63e6237c01fcaf3147839a8 Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Sat, 12 Mar 2022 20:02:00 +0100 Subject: [PATCH 41/46] extend the API for `LazyString` a bit (#44581) (cherry picked from commit e6c1525450fa27c4025094144b742011bb9cbb7e) --- base/strings/lazy.jl | 3 +++ test/strings/basic.jl | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/base/strings/lazy.jl b/base/strings/lazy.jl index b40fd9a5842b3..a2f872c40660e 100644 --- a/base/strings/lazy.jl +++ b/base/strings/lazy.jl @@ -61,3 +61,6 @@ iterate(s::LazyString, i::Integer) = iterate(String(s), i) isequal(a::LazyString, b::LazyString) = isequal(String(a), String(b)) ==(a::LazyString, b::LazyString) = (String(a) == String(b)) ncodeunits(s::LazyString) = ncodeunits(String(s)) +codeunit(s::LazyString) = codeunit(String(s)) +codeunit(s::LazyString, i::Integer) = codeunit(String(s), i) +isvalid(s::LazyString, i::Integer) = isvalid(String(s), i) diff --git a/test/strings/basic.jl b/test/strings/basic.jl index c1df87420d7da..b20c18e636db7 100644 --- a/test/strings/basic.jl +++ b/test/strings/basic.jl @@ -1100,4 +1100,8 @@ end let d = Dict(lazy"$(1+2) is 3" => 3) @test d["3 is 3"] == 3 end + l = lazy"1+2" + @test codeunit(l) == UInt8 + @test codeunit(l,2) == 0x2b + @test isvalid(l, 1) end From 20d32f5bf65dc7811fcb58bfe1257ca932414a1c Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Sat, 12 Mar 2022 19:09:16 -0500 Subject: [PATCH 42/46] inference: refine PartialStruct lattice tmerge (#44404) * inference: fix tmerge lattice over issimpleenoughtype Previously we assumed only union type could have complexity that violated the tmerge lattice requirements, but other types can have that too. This lets us fix an issue with the PartialStruct comparison failing for undefined fields, mentioned in #43784. * inference: refine PartialStruct lattice tmerge Be more aggressive about merging fields to greatly accelerate convergence, but also compute anyrefine more correctly as we do now elsewhere (since #42831, a121721f975fc4105ed24ebd0ad1020d08d07a38) Move the tmeet algorithm, without changes, since it is a precise lattice operation, not a heuristic limit like tmerge. Close #43784 (cherry picked from commit ff88fa446f44b8bcde15cea8c29549a6fff65375) --- base/compiler/typelattice.jl | 86 ++++++++++++++++++++++- base/compiler/typelimits.jl | 132 +++++++++++++++++++++-------------- test/compiler/inference.jl | 28 ++++++-- 3 files changed, 189 insertions(+), 57 deletions(-) diff --git a/base/compiler/typelattice.jl b/base/compiler/typelattice.jl index 1f55ceb94a062..eda1850604306 100644 --- a/base/compiler/typelattice.jl +++ b/base/compiler/typelattice.jl @@ -200,7 +200,7 @@ The non-strict partial order over the type inference lattice. end for i in 1:nfields(a.val) # XXX: let's handle varargs later - isdefined(a.val, i) || return false + isdefined(a.val, i) || continue # since ∀ T Union{} ⊑ T ⊑(Const(getfield(a.val, i)), b.fields[i]) || return false end return true @@ -289,6 +289,48 @@ function is_lattice_equal(@nospecialize(a), @nospecialize(b)) return a ⊑ b && b ⊑ a end +# compute typeintersect over the extended inference lattice, +# as precisely as we can, +# where v is in the extended lattice, and t is a Type. +function tmeet(@nospecialize(v), @nospecialize(t)) + if isa(v, Const) + if !has_free_typevars(t) && !isa(v.val, t) + return Bottom + end + return v + elseif isa(v, PartialStruct) + has_free_typevars(t) && return v + widev = widenconst(v) + if widev <: t + return v + end + ti = typeintersect(widev, t) + valid_as_lattice(ti) || return Bottom + @assert widev <: Tuple + new_fields = Vector{Any}(undef, length(v.fields)) + for i = 1:length(new_fields) + vfi = v.fields[i] + if isvarargtype(vfi) + new_fields[i] = vfi + else + new_fields[i] = tmeet(vfi, widenconst(getfield_tfunc(t, Const(i)))) + if new_fields[i] === Bottom + return Bottom + end + end + end + return tuple_tfunc(new_fields) + elseif isa(v, Conditional) + if !(Bool <: t) + return Bottom + end + return v + end + ti = typeintersect(widenconst(v), t) + valid_as_lattice(ti) || return Bottom + return ti +end + widenconst(c::AnyConditional) = Bool widenconst((; val)::Const) = isa(val, Type) ? Type{val} : typeof(val) widenconst(m::MaybeUndef) = widenconst(m.typ) @@ -425,3 +467,45 @@ function stupdate1!(state::VarTable, change::StateUpdate) end return false end + +# compute typeintersect over the extended inference lattice, +# as precisely as we can, +# where v is in the extended lattice, and t is a Type. +function tmeet(@nospecialize(v), @nospecialize(t)) + if isa(v, Const) + if !has_free_typevars(t) && !isa(v.val, t) + return Bottom + end + return v + elseif isa(v, PartialStruct) + has_free_typevars(t) && return v + widev = widenconst(v) + if widev <: t + return v + end + ti = typeintersect(widev, t) + valid_as_lattice(ti) || return Bottom + @assert widev <: Tuple + new_fields = Vector{Any}(undef, length(v.fields)) + for i = 1:length(new_fields) + vfi = v.fields[i] + if isvarargtype(vfi) + new_fields[i] = vfi + else + new_fields[i] = tmeet(vfi, widenconst(getfield_tfunc(t, Const(i)))) + if new_fields[i] === Bottom + return Bottom + end + end + end + return tuple_tfunc(new_fields) + elseif isa(v, Conditional) + if !(Bool <: t) + return Bottom + end + return v + end + ti = typeintersect(widenconst(v), t) + valid_as_lattice(ti) || return Bottom + return ti +end diff --git a/base/compiler/typelimits.jl b/base/compiler/typelimits.jl index a7989777317c3..d25c77deb6d2e 100644 --- a/base/compiler/typelimits.jl +++ b/base/compiler/typelimits.jl @@ -298,11 +298,57 @@ union_count_abstract(x::Union) = union_count_abstract(x.a) + union_count_abstrac union_count_abstract(@nospecialize(x)) = !isdispatchelem(x) function issimpleenoughtype(@nospecialize t) - t = ignorelimited(t) return unionlen(t) + union_count_abstract(t) <= MAX_TYPEUNION_LENGTH && unioncomplexity(t) <= MAX_TYPEUNION_COMPLEXITY end +# A simplified type_more_complex query over the extended lattice +# (assumes typeb ⊑ typea) +function issimplertype(@nospecialize(typea), @nospecialize(typeb)) + typea = ignorelimited(typea) + typeb = ignorelimited(typeb) + typea isa MaybeUndef && (typea = typea.typ) # n.b. does not appear in inference + typeb isa MaybeUndef && (typeb = typeb.typ) # n.b. does not appear in inference + typea === typeb && return true + if typea isa PartialStruct + aty = widenconst(typea) + for i = 1:length(typea.fields) + ai = typea.fields[i] + bi = fieldtype(aty, i) + is_lattice_equal(ai, bi) && continue + tni = _typename(widenconst(ai)) + if tni isa Const + bi = (tni.val::Core.TypeName).wrapper + is_lattice_equal(ai, bi) && continue + end + bi = getfield_tfunc(typeb, Const(i)) + is_lattice_equal(ai, bi) && continue + # It is not enough for ai to be simpler than bi: it must exactly equal + # (for this, an invariant struct field, by contrast to + # type_more_complex above which handles covariant tuples). + return false + end + elseif typea isa Type + return issimpleenoughtype(typea) + # elseif typea isa Const # fall-through good + elseif typea isa Conditional # follow issubconditional query + typeb isa Const && return true + typeb isa Conditional || return false + is_same_conditionals(typea, typeb) || return false + issimplertype(typea.vtype, typeb.vtype) || return false + issimplertype(typea.elsetype, typeb.elsetype) || return false + elseif typea isa InterConditional # ibid + typeb isa Const && return true + typeb isa InterConditional || return false + is_same_conditionals(typea, typeb) || return false + issimplertype(typea.vtype, typeb.vtype) || return false + issimplertype(typea.elsetype, typeb.elsetype) || return false + elseif typea isa PartialOpaque + # TODO + end + return true +end + # pick a wider type that contains both typea and typeb, # with some limits on how "large" it can get, # but without losing too much precision in common cases @@ -310,11 +356,13 @@ end function tmerge(@nospecialize(typea), @nospecialize(typeb)) typea === Union{} && return typeb typeb === Union{} && return typea + typea === typeb && return typea + suba = typea ⊑ typeb - suba && issimpleenoughtype(typeb) && return typeb + suba && issimplertype(typeb, typea) && return typeb subb = typeb ⊑ typea suba && subb && return typea - subb && issimpleenoughtype(typea) && return typea + subb && issimplertype(typea, typeb) && return typea # type-lattice for LimitedAccuracy wrapper # the merge create a slightly narrower type than needed, but we can't @@ -404,6 +452,7 @@ function tmerge(@nospecialize(typea), @nospecialize(typeb)) aty = widenconst(typea) bty = widenconst(typeb) if aty === bty + # must have egal here, since we do not create PartialStruct for non-concrete types typea_nfields = nfields_tfunc(typea) typeb_nfields = nfields_tfunc(typeb) isa(typea_nfields, Const) || return aty @@ -412,18 +461,40 @@ function tmerge(@nospecialize(typea), @nospecialize(typeb)) type_nfields === typeb_nfields.val::Int || return aty type_nfields == 0 && return aty fields = Vector{Any}(undef, type_nfields) - anyconst = false + anyrefine = false for i = 1:type_nfields ai = getfield_tfunc(typea, Const(i)) bi = getfield_tfunc(typeb, Const(i)) - ity = tmerge(ai, bi) - if ai === Union{} || bi === Union{} - ity = widenconst(ity) + ft = fieldtype(aty, i) + if is_lattice_equal(ai, bi) || is_lattice_equal(ai, ft) + # Since ai===bi, the given type has no restrictions on complexity. + # and can be used to refine ft + tyi = ai + elseif is_lattice_equal(bi, ft) + tyi = bi + else + # Otherwise choose between using the fieldtype or some other simple merged type. + # The wrapper type never has restrictions on complexity, + # so try to use that to refine the estimated type too. + tni = _typename(widenconst(ai)) + if tni isa Const && tni === _typename(widenconst(bi)) + # A tmeet call may cause tyi to become complex, but since the inputs were + # strictly limited to being egal, this has no restrictions on complexity. + # (Otherwise, we would need to use <: and take the narrower one without + # intersection. See the similar comment in abstract_call_method.) + tyi = typeintersect(ft, (tni.val::Core.TypeName).wrapper) + else + # Since aty===bty, the fieldtype has no restrictions on complexity. + tyi = ft + end + end + fields[i] = tyi + if !anyrefine + anyrefine = has_nontrivial_const_info(tyi) || # constant information + tyi ⋤ ft # just a type-level information, but more precise than the declared type end - fields[i] = ity - anyconst |= has_nontrivial_const_info(ity) end - return anyconst ? PartialStruct(aty, fields) : aty + return anyrefine ? PartialStruct(aty, fields) : aty end end if isa(typea, PartialOpaque) && isa(typeb, PartialOpaque) && widenconst(typea) == widenconst(typeb) @@ -610,44 +681,3 @@ function tuplemerge(a::DataType, b::DataType) end return Tuple{p...} end - -# compute typeintersect over the extended inference lattice -# where v is in the extended lattice, and t is a Type -function tmeet(@nospecialize(v), @nospecialize(t)) - if isa(v, Const) - if !has_free_typevars(t) && !isa(v.val, t) - return Bottom - end - return v - elseif isa(v, PartialStruct) - has_free_typevars(t) && return v - widev = widenconst(v) - if widev <: t - return v - end - ti = typeintersect(widev, t) - valid_as_lattice(ti) || return Bottom - @assert widev <: Tuple - new_fields = Vector{Any}(undef, length(v.fields)) - for i = 1:length(new_fields) - vfi = v.fields[i] - if isvarargtype(vfi) - new_fields[i] = vfi - else - new_fields[i] = tmeet(vfi, widenconst(getfield_tfunc(t, Const(i)))) - if new_fields[i] === Bottom - return Bottom - end - end - end - return tuple_tfunc(new_fields) - elseif isa(v, Conditional) - if !(Bool <: t) - return Bottom - end - return v - end - ti = typeintersect(widenconst(v), t) - valid_as_lattice(ti) || return Bottom - return ti -end diff --git a/test/compiler/inference.jl b/test/compiler/inference.jl index 61058f9589f52..218e484b2beca 100644 --- a/test/compiler/inference.jl +++ b/test/compiler/inference.jl @@ -3999,15 +3999,33 @@ end @test ⊑(a, c) @test ⊑(b, c) - @test @eval Module() begin - const ginit = Base.ImmutableDict{Any,Any}() - Base.return_types() do - g = ginit + init = Base.ImmutableDict{Number,Number}() + a = Const(init) + b = Core.PartialStruct(typeof(init), Any[Const(init), Any, ComplexF64]) + c = Core.Compiler.tmerge(a, b) + @test ⊑(a, c) && ⊑(b, c) + @test c === typeof(init) + + a = Core.PartialStruct(typeof(init), Any[Const(init), ComplexF64, ComplexF64]) + c = Core.Compiler.tmerge(a, b) + @test ⊑(a, c) && ⊑(b, c) + @test c.fields[2] === Any # or Number + @test c.fields[3] === ComplexF64 + + b = Core.PartialStruct(typeof(init), Any[Const(init), ComplexF32, Union{ComplexF32,ComplexF64}]) + c = Core.Compiler.tmerge(a, b) + @test ⊑(a, c) + @test ⊑(b, c) + @test c.fields[2] === Complex + @test c.fields[3] === Complex + + global const ginit43784 = Base.ImmutableDict{Any,Any}() + @test Base.return_types() do + g = ginit43784 while true g = Base.ImmutableDict(g, 1=>2) end end |> only === Union{} - end end # Test that purity modeling doesn't accidentally introduce new world age issues From 0e58e8b56e097320ed47f210db1dd8033a8566cc Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki Date: Mon, 14 Mar 2022 15:44:37 +0900 Subject: [PATCH 43/46] take in changes of #44608 and #44609 --- NEWS.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/NEWS.md b/NEWS.md index 4783338b4b525..73ca691ab7c3f 100644 --- a/NEWS.md +++ b/NEWS.md @@ -13,7 +13,7 @@ New language features no errors were thrown ([#42211]). * `@inline` and `@noinline` annotations can now be placed within a function body ([#41312]). * `@inline` and `@noinline` annotations can now be applied to a function call site or block - to enforce the involved function calls to be (or not to be) inlined ([#41312]). + to enforce the involved function calls to be (or not to be) inlined ([#41328]). * `∀`, `∃`, and `∄` are now allowed as identifier characters ([#42314]). * Support for Unicode 14.0.0 ([#43443]). * `Module(:name, false, false)` can be used to create a `module` that contains no names @@ -237,7 +237,7 @@ Tooling Improvements * `GC.enable_logging(true)` can be used to log each garbage collection, with the time it took and the amount of memory that was collected ([#43511]). - + [Pkg#2284]: https://github.com/JuliaLang/Pkg.jl/issues/2284 [Pkg#2689]: https://github.com/JuliaLang/Pkg.jl/issues/2689 @@ -263,6 +263,7 @@ Tooling Improvements [#40980]: https://github.com/JuliaLang/julia/issues/40980 [#41085]: https://github.com/JuliaLang/julia/issues/41085 [#41312]: https://github.com/JuliaLang/julia/issues/41312 +[#41328]: https://github.com/JuliaLang/julia/issues/41328 [#41449]: https://github.com/JuliaLang/julia/issues/41449 [#41551]: https://github.com/JuliaLang/julia/issues/41551 [#41576]: https://github.com/JuliaLang/julia/issues/41576 From c790036ad2328543d9f63218320908bfe6159694 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Thu, 3 Mar 2022 23:18:11 -0500 Subject: [PATCH 44/46] fix error msg test on 32-bit (#44441) (cherry picked from commit 8c4ff5540423a9dd088e4366054a3c83a6f36353) --- test/error.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/error.jl b/test/error.jl index 9b87cb6fff185..913d303496e3e 100644 --- a/test/error.jl +++ b/test/error.jl @@ -93,6 +93,6 @@ end f44319(1) catch e s = sprint(showerror, e) - @test s == "MethodError: no method matching f44319(::Int64)\nClosest candidates are:\n f44319() at none:0" + @test s == "MethodError: no method matching f44319(::Int$(Sys.WORD_SIZE))\nClosest candidates are:\n f44319() at none:0" end end From 510b53f404d23d930b27af85eccfdcba4c49863d Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Tue, 15 Mar 2022 11:04:35 +0900 Subject: [PATCH 45/46] effects: complements #43852, implement effect override mechanisms (#44561) The PR #43852 missed to implement the mechanism to override analyzed effects with effect settings annotated by `Base.@assume_effects`. This commits adds such an mechanism within `finish(::InferenceState, ::AbstractInterpreter)`, just after inference analyzed frame effect. Now we can do something like: ```julia Base.@assume_effects :consistent :effect_free :terminates_globally consteval( f, args...; kwargs...) = f(args...; kwargs...) const ___CONST_DICT___ = Dict{Any,Any}(:a => 1, :b => 2) @test fully_eliminated() do consteval(getindex, ___CONST_DICT___, :a) end ``` --- base/compiler/abstractinterpretation.jl | 17 +++---- base/compiler/inferencestate.jl | 15 +++++++ base/compiler/typeinfer.jl | 28 ++++++++---- base/compiler/types.jl | 60 ++++++++++++++++++------- test/compiler/inline.jl | 7 +++ 5 files changed, 91 insertions(+), 36 deletions(-) diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index 14f37ff87c464..770fa51b47966 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -598,10 +598,12 @@ function abstract_call_method(interp::AbstractInterpreter, method::Method, @nosp if edge === nothing edgecycle = edgelimited = true end - if is_effect_overrided(sv, :terminates_globally) + # we look for the termination effect override here as well, since the :terminates effect + # may have been tainted due to recursion at this point even if it's overridden + if is_effect_overridden(sv, :terminates_globally) # this frame is known to terminate edge_effects = Effects(edge_effects, terminates=ALWAYS_TRUE) - elseif is_effect_overrided(method, :terminates_globally) + elseif is_effect_overridden(method, :terminates_globally) # this edge is known to terminate edge_effects = Effects(edge_effects, terminates=ALWAYS_TRUE) elseif edgecycle @@ -612,13 +614,6 @@ function abstract_call_method(interp::AbstractInterpreter, method::Method, @nosp return MethodCallResult(rt, edgecycle, edgelimited, edge, edge_effects) end -is_effect_overrided(sv::InferenceState, effect::Symbol) = is_effect_overrided(sv.linfo, effect) -function is_effect_overrided(linfo::MethodInstance, effect::Symbol) - def = linfo.def - return isa(def, Method) && is_effect_overrided(def, effect) -end -is_effect_overrided(method::Method, effect::Symbol) = getfield(decode_effects_override(method.purity), effect) - # keeps result and context information of abstract method call, will be used by succeeding constant-propagation struct MethodCallResult rt @@ -2093,9 +2088,9 @@ end function handle_control_backedge!(frame::InferenceState, from::Int, to::Int) if from > to - if is_effect_overrided(frame, :terminates_globally) + if is_effect_overridden(frame, :terminates_globally) # this frame is known to terminate - elseif is_effect_overrided(frame, :terminates_locally) + elseif is_effect_overridden(frame, :terminates_locally) # this backedge is known to terminate else tristate_merge!(frame, Effects(EFFECTS_TOTAL, terminates=TRISTATE_UNKNOWN)) diff --git a/base/compiler/inferencestate.jl b/base/compiler/inferencestate.jl index 928811dd63a3b..12de1b6705aa9 100644 --- a/base/compiler/inferencestate.jl +++ b/base/compiler/inferencestate.jl @@ -141,8 +141,23 @@ mutable struct InferenceState return frame end end + Effects(state::InferenceState) = state.ipo_effects +function tristate_merge!(caller::InferenceState, effects::Effects) + caller.ipo_effects = tristate_merge(caller.ipo_effects, effects) +end +tristate_merge!(caller::InferenceState, callee::InferenceState) = + tristate_merge!(caller, Effects(callee)) + +is_effect_overridden(sv::InferenceState, effect::Symbol) = is_effect_overridden(sv.linfo, effect) +function is_effect_overridden(linfo::MethodInstance, effect::Symbol) + def = linfo.def + return isa(def, Method) && is_effect_overridden(def, effect) +end +is_effect_overridden(method::Method, effect::Symbol) = is_effect_overridden(decode_effects_override(method.purity), effect) +is_effect_overridden(override::EffectsOverride, effect::Symbol) = getfield(override, effect) + function any_inbounds(code::Vector{Any}) for i=1:length(code) stmt = code[i] diff --git a/base/compiler/typeinfer.jl b/base/compiler/typeinfer.jl index 4015b7c00bf0d..a047222cbfee0 100644 --- a/base/compiler/typeinfer.jl +++ b/base/compiler/typeinfer.jl @@ -494,7 +494,25 @@ function finish(me::InferenceState, interp::AbstractInterpreter) end me.result.valid_worlds = me.valid_worlds me.result.result = me.bestguess - me.result.ipo_effects = rt_adjust_effects(me.bestguess, me.ipo_effects) + ipo_effects = rt_adjust_effects(me.bestguess, me.ipo_effects) + # override the analyzed effects using manually annotated effect settings + def = me.linfo.def + if isa(def, Method) + override = decode_effects_override(def.purity) + if is_effect_overridden(override, :consistent) + ipo_effects = Effects(ipo_effects; consistent=ALWAYS_TRUE) + end + if is_effect_overridden(override, :effect_free) + ipo_effects = Effects(ipo_effects; effect_free=ALWAYS_TRUE) + end + if is_effect_overridden(override, :nothrow) + ipo_effects = Effects(ipo_effects; nothrow=ALWAYS_TRUE) + end + if is_effect_overridden(override, :terminates_globally) + ipo_effects = Effects(ipo_effects; terminates=ALWAYS_TRUE) + end + end + me.result.ipo_effects = ipo_effects validate_code_in_debug_mode(me.linfo, me.src, "inferred") nothing end @@ -797,14 +815,6 @@ end generating_sysimg() = ccall(:jl_generating_output, Cint, ()) != 0 && JLOptions().incremental == 0 -function tristate_merge!(caller::InferenceState, callee::Effects) - caller.ipo_effects = tristate_merge(caller.ipo_effects, callee) -end - -function tristate_merge!(caller::InferenceState, callee::InferenceState) - tristate_merge!(caller, Effects(callee)) -end - ipo_effects(code::CodeInstance) = decode_effects(code.ipo_purity_bits) # compute (and cache) an inferred AST and return the current best estimate of the result type diff --git a/base/compiler/types.jl b/base/compiler/types.jl index 6d4a650470237..65ce341dd55e1 100644 --- a/base/compiler/types.jl +++ b/base/compiler/types.jl @@ -42,14 +42,33 @@ struct Effects # :consistent before caching. We may want to track it in the future. inbounds_taints_consistency::Bool end -Effects(consistent::TriState, effect_free::TriState, nothrow::TriState, terminates::TriState) = - Effects(consistent, effect_free, nothrow, terminates, false) +function Effects( + consistent::TriState, + effect_free::TriState, + nothrow::TriState, + terminates::TriState) + return Effects( + consistent, + effect_free, + nothrow, + terminates, + false) +end Effects() = Effects(TRISTATE_UNKNOWN, TRISTATE_UNKNOWN, TRISTATE_UNKNOWN, TRISTATE_UNKNOWN) -Effects(e::Effects; consistent::TriState=e.consistent, - effect_free::TriState = e.effect_free, nothrow::TriState=e.nothrow, terminates::TriState=e.terminates, - inbounds_taints_consistency::Bool = e.inbounds_taints_consistency) = - Effects(consistent, effect_free, nothrow, terminates, inbounds_taints_consistency) +function Effects(e::Effects; + consistent::TriState = e.consistent, + effect_free::TriState = e.effect_free, + nothrow::TriState = e.nothrow, + terminates::TriState = e.terminates, + inbounds_taints_consistency::Bool = e.inbounds_taints_consistency) + return Effects( + consistent, + effect_free, + nothrow, + terminates, + inbounds_taints_consistency) +end is_total_or_error(effects::Effects) = effects.consistent === ALWAYS_TRUE && effects.effect_free === ALWAYS_TRUE && @@ -65,15 +84,24 @@ is_removable_if_unused(effects::Effects) = const EFFECTS_TOTAL = Effects(ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE) -encode_effects(e::Effects) = e.consistent.state | (e.effect_free.state << 2) | (e.nothrow.state << 4) | (e.terminates.state << 6) -decode_effects(e::UInt8) = - Effects(TriState(e & 0x3), +function encode_effects(e::Effects) + return e.consistent.state | + (e.effect_free.state << 2) | + (e.nothrow.state << 4) | + (e.terminates.state << 6) +end +function decode_effects(e::UInt8) + return Effects( + TriState(e & 0x3), TriState((e >> 2) & 0x3), TriState((e >> 4) & 0x3), - TriState((e >> 6) & 0x3), false) + TriState((e >> 6) & 0x3), + false) +end function tristate_merge(old::Effects, new::Effects) - Effects(tristate_merge( + return Effects( + tristate_merge( old.consistent, new.consistent), tristate_merge( old.effect_free, new.effect_free), @@ -81,8 +109,7 @@ function tristate_merge(old::Effects, new::Effects) old.nothrow, new.nothrow), tristate_merge( old.terminates, new.terminates), - old.inbounds_taints_consistency || - new.inbounds_taints_consistency) + old.inbounds_taints_consistency | new.inbounds_taints_consistency) end struct EffectsOverride @@ -100,16 +127,17 @@ function encode_effects_override(eo::EffectsOverride) eo.nothrow && (e |= 0x04) eo.terminates_globally && (e |= 0x08) eo.terminates_locally && (e |= 0x10) - e + return e end -decode_effects_override(e::UInt8) = - EffectsOverride( +function decode_effects_override(e::UInt8) + return EffectsOverride( (e & 0x01) != 0x00, (e & 0x02) != 0x00, (e & 0x04) != 0x00, (e & 0x08) != 0x00, (e & 0x10) != 0x00) +end """ InferenceResult diff --git a/test/compiler/inline.jl b/test/compiler/inline.jl index 3259c752d9aa0..1af52422b2f71 100644 --- a/test/compiler/inline.jl +++ b/test/compiler/inline.jl @@ -1088,6 +1088,13 @@ recur_termination22(x) = x * recur_termination21(x-1) recur_termination21(12) + recur_termination22(12) end +const ___CONST_DICT___ = Dict{Any,Any}(:a => 1, :b => 2) +Base.@assume_effects :consistent :effect_free :terminates_globally consteval( + f, args...; kwargs...) = f(args...; kwargs...) +@test fully_eliminated() do + consteval(getindex, ___CONST_DICT___, :a) +end + global x44200::Int = 0 function f44200() global x = 0 From e1e02f6a89f931e996944b31c333ce14e33858a2 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Tue, 15 Mar 2022 18:26:33 +0900 Subject: [PATCH 46/46] Merge pull request #44515 from JuliaLang/avi/partialeval `AbstractInterpreter`: enable selective concrete-evaluation for external `AbstractInterpreter` with overlayed method table --- base/compiler/abstractinterpretation.jl | 120 +++++++++++++++--------- base/compiler/inferencestate.jl | 2 +- base/compiler/methodtable.jl | 60 +++++++----- base/compiler/ssair/show.jl | 1 + base/compiler/tfuncs.jl | 12 ++- base/compiler/typeinfer.jl | 6 +- base/compiler/types.jl | 36 ++++--- base/reflection.jl | 5 +- test/compiler/AbstractInterpreter.jl | 54 ++++++++--- 9 files changed, 192 insertions(+), 104 deletions(-) diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index 770fa51b47966..2efb660a32fb5 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -39,15 +39,31 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f), # function has not seen any side effects, we would like to make sure there # aren't any in the throw block either to enable other optimizations. add_remark!(interp, sv, "Skipped call in throw block") + overlayed = true + if isoverlayed(method_table(interp)) + if !sv.ipo_effects.overlayed + # as we may want to concrete-evaluate this frame in cases when there are + # no overlayed calls, try an additional effort now to check if this call + # isn't overlayed rather than just handling it conservatively + matches = find_matching_methods(arginfo.argtypes, atype, method_table(interp), + InferenceParams(interp).MAX_UNION_SPLITTING, max_methods) + if !isa(matches, FailedMethodMatch) + overlayed = matches.overlayed + end + end + else + overlayed = false + end # At this point we are guaranteed to end up throwing on this path, # which is all that's required for :consistent-cy. Of course, we don't # know anything else about this statement. - tristate_merge!(sv, Effects(Effects(), consistent=ALWAYS_TRUE)) + tristate_merge!(sv, Effects(; consistent=ALWAYS_TRUE, overlayed)) return CallMeta(Any, false) end argtypes = arginfo.argtypes - matches = find_matching_methods(argtypes, atype, method_table(interp), InferenceParams(interp).MAX_UNION_SPLITTING, max_methods) + matches = find_matching_methods(argtypes, atype, method_table(interp), + InferenceParams(interp).MAX_UNION_SPLITTING, max_methods) if isa(matches, FailedMethodMatch) add_remark!(interp, sv, matches.reason) tristate_merge!(sv, Effects()) @@ -64,6 +80,12 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f), any_const_result = false const_results = Union{InferenceResult,Nothing,ConstResult}[] multiple_matches = napplicable > 1 + if matches.overlayed + # currently we don't have a good way to execute the overlayed method definition, + # so we should give up pure/concrete eval when any of the matched methods is overlayed + f = nothing + tristate_merge!(sv, Effects(EFFECTS_TOTAL; overlayed=true)) + end val = pure_eval_call(interp, f, applicable, arginfo, sv) val !== nothing && return CallMeta(val, MethodResultPure(info)) # TODO: add some sort of edge(s) @@ -94,7 +116,8 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f), end this_argtypes = isa(matches, MethodMatches) ? argtypes : matches.applicable_argtypes[i] this_arginfo = ArgInfo(fargs, this_argtypes) - const_call_result = abstract_call_method_with_const_args(interp, result, f, this_arginfo, match, sv) + const_call_result = abstract_call_method_with_const_args(interp, result, + f, this_arginfo, match, sv) effects = result.edge_effects const_result = nothing if const_call_result !== nothing @@ -136,7 +159,8 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f), # this is in preparation for inlining, or improving the return result this_argtypes = isa(matches, MethodMatches) ? argtypes : matches.applicable_argtypes[i] this_arginfo = ArgInfo(fargs, this_argtypes) - const_call_result = abstract_call_method_with_const_args(interp, result, f, this_arginfo, match, sv) + const_call_result = abstract_call_method_with_const_args(interp, result, + f, this_arginfo, match, sv) effects = result.edge_effects const_result = nothing if const_call_result !== nothing @@ -181,11 +205,11 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f), end if seen != napplicable - tristate_merge!(sv, Effects()) + tristate_merge!(sv, Effects(; overlayed=false)) # already accounted for method overlay above elseif isa(matches, MethodMatches) ? (!matches.fullmatch || any_ambig(matches)) : (!_all(b->b, matches.fullmatches) || any_ambig(matches)) # Account for the fact that we may encounter a MethodError with a non-covered or ambiguous signature. - tristate_merge!(sv, Effects(EFFECTS_TOTAL, nothrow=TRISTATE_UNKNOWN)) + tristate_merge!(sv, Effects(EFFECTS_TOTAL; nothrow=TRISTATE_UNKNOWN)) end rettype = from_interprocedural!(rettype, sv, arginfo, conditionals) @@ -220,6 +244,7 @@ struct MethodMatches valid_worlds::WorldRange mt::Core.MethodTable fullmatch::Bool + overlayed::Bool end any_ambig(info::MethodMatchInfo) = info.results.ambig any_ambig(m::MethodMatches) = any_ambig(m.info) @@ -231,6 +256,7 @@ struct UnionSplitMethodMatches valid_worlds::WorldRange mts::Vector{Core.MethodTable} fullmatches::Vector{Bool} + overlayed::Bool end any_ambig(m::UnionSplitMethodMatches) = _any(any_ambig, m.info.matches) @@ -245,16 +271,19 @@ function find_matching_methods(argtypes::Vector{Any}, @nospecialize(atype), meth valid_worlds = WorldRange() mts = Core.MethodTable[] fullmatches = Bool[] + overlayed = false for i in 1:length(split_argtypes) arg_n = split_argtypes[i]::Vector{Any} sig_n = argtypes_to_type(arg_n) mt = ccall(:jl_method_table_for, Any, (Any,), sig_n) mt === nothing && return FailedMethodMatch("Could not identify method table for call") mt = mt::Core.MethodTable - matches = findall(sig_n, method_table; limit = max_methods) - if matches === missing + result = findall(sig_n, method_table; limit = max_methods) + if result === missing return FailedMethodMatch("For one of the union split cases, too many methods matched") end + matches, overlayedᵢ = result + overlayed |= overlayedᵢ push!(infos, MethodMatchInfo(matches)) for m in matches push!(applicable, m) @@ -280,25 +309,28 @@ function find_matching_methods(argtypes::Vector{Any}, @nospecialize(atype), meth UnionSplitInfo(infos), valid_worlds, mts, - fullmatches) + fullmatches, + overlayed) else mt = ccall(:jl_method_table_for, Any, (Any,), atype) if mt === nothing return FailedMethodMatch("Could not identify method table for call") end mt = mt::Core.MethodTable - matches = findall(atype, method_table; limit = max_methods) - if matches === missing + result = findall(atype, method_table; limit = max_methods) + if result === missing # this means too many methods matched # (assume this will always be true, so we don't compute / update valid age in this case) return FailedMethodMatch("Too many methods matched") end + matches, overlayed = result fullmatch = _any(match->(match::MethodMatch).fully_covers, matches) return MethodMatches(matches.matches, MethodMatchInfo(matches), matches.valid_worlds, mt, - fullmatch) + fullmatch, + overlayed) end end @@ -605,11 +637,11 @@ function abstract_call_method(interp::AbstractInterpreter, method::Method, @nosp edge_effects = Effects(edge_effects, terminates=ALWAYS_TRUE) elseif is_effect_overridden(method, :terminates_globally) # this edge is known to terminate - edge_effects = Effects(edge_effects, terminates=ALWAYS_TRUE) + edge_effects = Effects(edge_effects; terminates=ALWAYS_TRUE) elseif edgecycle # Some sort of recursion was detected. Even if we did not limit types, # we cannot guarantee that the call will terminate - edge_effects = Effects(edge_effects, terminates=TRISTATE_UNKNOWN) + edge_effects = Effects(edge_effects; terminates=TRISTATE_UNKNOWN) end return MethodCallResult(rt, edgecycle, edgelimited, edge, edge_effects) end @@ -632,8 +664,8 @@ end function pure_eval_eligible(interp::AbstractInterpreter, @nospecialize(f), applicable::Vector{Any}, arginfo::ArgInfo, sv::InferenceState) - return !isoverlayed(method_table(interp)) && - f !== nothing && + # XXX we need to check that this pure function doesn't call any overlayed method + return f !== nothing && length(applicable) == 1 && is_method_pure(applicable[1]::MethodMatch) && is_all_const_arg(arginfo) @@ -669,8 +701,10 @@ end function concrete_eval_eligible(interp::AbstractInterpreter, @nospecialize(f), result::MethodCallResult, arginfo::ArgInfo, sv::InferenceState) - return !isoverlayed(method_table(interp)) && - f !== nothing && + # disable concrete-evaluation since this function call is tainted by some overlayed + # method and currently there is no direct way to execute overlayed methods + isoverlayed(method_table(interp)) && result.edge_effects.overlayed && return false + return f !== nothing && result.edge !== nothing && is_total_or_error(result.edge_effects) && is_all_const_arg(arginfo) @@ -1469,7 +1503,7 @@ function abstract_invoke(interp::AbstractInterpreter, (; fargs, argtypes)::ArgIn types = rewrap_unionall(Tuple{ft, unwrap_unionall(types).parameters...}, types)::Type nargtype = Tuple{ft, nargtype.parameters...} argtype = Tuple{ft, argtype.parameters...} - match, valid_worlds = findsup(types, method_table(interp)) + match, valid_worlds, overlayed = findsup(types, method_table(interp)) match === nothing && return CallMeta(Any, false) update_valid_age!(sv, valid_worlds) method = match.method @@ -1487,7 +1521,8 @@ function abstract_invoke(interp::AbstractInterpreter, (; fargs, argtypes)::ArgIn # t, a = ti.parameters[i], argtypes′[i] # argtypes′[i] = t ⊑ a ? t : a # end - const_call_result = abstract_call_method_with_const_args(interp, result, singleton_type(ft′), arginfo, match, sv) + const_call_result = abstract_call_method_with_const_args(interp, result, + overlayed ? nothing : singleton_type(ft′), arginfo, match, sv) const_result = nothing if const_call_result !== nothing if const_call_result.rt ⊑ rt @@ -1518,7 +1553,7 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f), call = abstract_invoke(interp, arginfo, sv) if call.info === false if call.rt === Bottom - tristate_merge!(sv, Effects(EFFECTS_TOTAL, nothrow=ALWAYS_FALSE)) + tristate_merge!(sv, Effects(EFFECTS_TOTAL; nothrow=ALWAYS_FALSE)) else tristate_merge!(sv, Effects()) end @@ -1545,12 +1580,12 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f), end end end - tristate_merge!(sv, Effects()) # TODO + tristate_merge!(sv, Effects(; overlayed=false)) # TODO return CallMeta(Any, false) elseif f === TypeVar # Manually look through the definition of TypeVar to # make sure to be able to get `PartialTypeVar`s out. - tristate_merge!(sv, Effects()) # TODO + tristate_merge!(sv, Effects(; overlayed=false)) # TODO (la < 2 || la > 4) && return CallMeta(Union{}, false) n = argtypes[2] ub_var = Const(Any) @@ -1563,17 +1598,17 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f), end return CallMeta(typevar_tfunc(n, lb_var, ub_var), false) elseif f === UnionAll - tristate_merge!(sv, Effects()) # TODO + tristate_merge!(sv, Effects(; overlayed=false)) # TODO return CallMeta(abstract_call_unionall(argtypes), false) elseif f === Tuple && la == 2 - tristate_merge!(sv, Effects()) # TODO + tristate_merge!(sv, Effects(; overlayed=false)) # TODO aty = argtypes[2] ty = isvarargtype(aty) ? unwrapva(aty) : widenconst(aty) if !isconcretetype(ty) return CallMeta(Tuple, false) end elseif is_return_type(f) - tristate_merge!(sv, Effects()) # TODO + tristate_merge!(sv, Effects(; overlayed=false)) # TODO return return_type_tfunc(interp, argtypes, sv) elseif la == 2 && istopfunction(f, :!) # handle Conditional propagation through !Bool @@ -1637,8 +1672,8 @@ function abstract_call_opaque_closure(interp::AbstractInterpreter, closure::Part match = MethodMatch(sig, Core.svec(), closure.source, sig <: rewrap_unionall(sigT, tt)) const_result = nothing if !result.edgecycle - const_call_result = abstract_call_method_with_const_args(interp, result, nothing, - arginfo, match, sv) + const_call_result = abstract_call_method_with_const_args(interp, result, + nothing, arginfo, match, sv) if const_call_result !== nothing if const_call_result.rt ⊑ rt (; rt, const_result) = const_call_result @@ -1825,9 +1860,9 @@ function abstract_eval_statement(interp::AbstractInterpreter, @nospecialize(e), at = tmeet(at, ft) if at === Bottom t = Bottom - tristate_merge!(sv, Effects( - ALWAYS_TRUE, # N.B depends on !ismutabletype(t) above - ALWAYS_TRUE, ALWAYS_FALSE, ALWAYS_TRUE)) + tristate_merge!(sv, Effects(EFFECTS_TOTAL; + # consistent = ALWAYS_TRUE, # N.B depends on !ismutabletype(t) above + nothrow = ALWAYS_FALSE)) @goto t_computed elseif !isa(at, Const) allconst = false @@ -1855,7 +1890,7 @@ function abstract_eval_statement(interp::AbstractInterpreter, @nospecialize(e), else is_nothrow = false end - tristate_merge!(sv, Effects(EFFECTS_TOTAL, + tristate_merge!(sv, Effects(EFFECTS_TOTAL; consistent = !ismutabletype(t) ? ALWAYS_TRUE : ALWAYS_FALSE, nothrow = is_nothrow ? ALWAYS_TRUE : ALWAYS_FALSE)) elseif ehead === :splatnew @@ -1874,7 +1909,7 @@ function abstract_eval_statement(interp::AbstractInterpreter, @nospecialize(e), t = PartialStruct(t, at.fields::Vector{Any}) end end - tristate_merge!(sv, Effects(EFFECTS_TOTAL, + tristate_merge!(sv, Effects(EFFECTS_TOTAL; consistent = ismutabletype(t) ? ALWAYS_FALSE : ALWAYS_TRUE, nothrow = is_nothrow ? ALWAYS_TRUE : ALWAYS_FALSE)) elseif ehead === :new_opaque_closure @@ -1916,20 +1951,21 @@ function abstract_eval_statement(interp::AbstractInterpreter, @nospecialize(e), effects.effect_free ? ALWAYS_TRUE : TRISTATE_UNKNOWN, effects.nothrow ? ALWAYS_TRUE : TRISTATE_UNKNOWN, effects.terminates_globally ? ALWAYS_TRUE : TRISTATE_UNKNOWN, + #=overlayed=#false )) else - tristate_merge!(sv, Effects()) + tristate_merge!(sv, Effects(; overlayed=false)) end elseif ehead === :cfunction - tristate_merge!(sv, Effects()) + tristate_merge!(sv, Effects(; overlayed=false)) t = e.args[1] isa(t, Type) || (t = Any) abstract_eval_cfunction(interp, e, vtypes, sv) elseif ehead === :method - tristate_merge!(sv, Effects()) + tristate_merge!(sv, Effects(; overlayed=false)) t = (length(e.args) == 1) ? Any : Nothing elseif ehead === :copyast - tristate_merge!(sv, Effects()) + tristate_merge!(sv, Effects(; overlayed=false)) t = abstract_eval_value(interp, e.args[1], vtypes, sv) if t isa Const && t.val isa Expr # `copyast` makes copies of Exprs @@ -1999,9 +2035,9 @@ function abstract_eval_global(M::Module, s::Symbol, frame::InferenceState) ty = abstract_eval_global(M, s) isa(ty, Const) && return ty if isdefined(M,s) - tristate_merge!(frame, Effects(EFFECTS_TOTAL, consistent=ALWAYS_FALSE)) + tristate_merge!(frame, Effects(EFFECTS_TOTAL; consistent=ALWAYS_FALSE)) else - tristate_merge!(frame, Effects(EFFECTS_TOTAL, consistent=ALWAYS_FALSE, nothrow=ALWAYS_FALSE)) + tristate_merge!(frame, Effects(EFFECTS_TOTAL; consistent=ALWAYS_FALSE, nothrow=ALWAYS_FALSE)) end return ty end @@ -2093,7 +2129,7 @@ function handle_control_backedge!(frame::InferenceState, from::Int, to::Int) elseif is_effect_overridden(frame, :terminates_locally) # this backedge is known to terminate else - tristate_merge!(frame, Effects(EFFECTS_TOTAL, terminates=TRISTATE_UNKNOWN)) + tristate_merge!(frame, Effects(EFFECTS_TOTAL; terminates=TRISTATE_UNKNOWN)) end end return nothing @@ -2251,11 +2287,11 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState) if isa(lhs, SlotNumber) changes = StateUpdate(lhs, VarState(t, false), changes, false) elseif isa(lhs, GlobalRef) - tristate_merge!(frame, Effects(EFFECTS_TOTAL, + tristate_merge!(frame, Effects(EFFECTS_TOTAL; effect_free=ALWAYS_FALSE, nothrow=TRISTATE_UNKNOWN)) elseif !isa(lhs, SSAValue) - tristate_merge!(frame, Effects()) + tristate_merge!(frame, Effects(; overlayed=false)) end elseif hd === :method stmt = stmt::Expr diff --git a/base/compiler/inferencestate.jl b/base/compiler/inferencestate.jl index 12de1b6705aa9..db6ab574e3859 100644 --- a/base/compiler/inferencestate.jl +++ b/base/compiler/inferencestate.jl @@ -134,7 +134,7 @@ mutable struct InferenceState #=parent=#nothing, #=cached=#cache === :global, #=inferred=#false, #=dont_work_on_me=#false, - #=ipo_effects=#Effects(consistent, ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE, inbounds_taints_consistency), + #=ipo_effects=#Effects(consistent, ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE, false, inbounds_taints_consistency), interp) result.result = frame cache !== :no && push!(get_inference_cache(interp), result) diff --git a/base/compiler/methodtable.jl b/base/compiler/methodtable.jl index f68cdd52d1b06..da493cf9a9ef5 100644 --- a/base/compiler/methodtable.jl +++ b/base/compiler/methodtable.jl @@ -40,15 +40,18 @@ end getindex(result::MethodLookupResult, idx::Int) = getindex(result.matches, idx)::MethodMatch """ - findall(sig::Type, view::MethodTableView; limit::Int=typemax(Int)) -> MethodLookupResult or missing + findall(sig::Type, view::MethodTableView; limit::Int=typemax(Int)) -> + (matches::MethodLookupResult, overlayed::Bool) or missing -Find all methods in the given method table `view` that are applicable to the -given signature `sig`. If no applicable methods are found, an empty result is -returned. If the number of applicable methods exceeded the specified limit, -`missing` is returned. +Find all methods in the given method table `view` that are applicable to the given signature `sig`. +If no applicable methods are found, an empty result is returned. +If the number of applicable methods exceeded the specified limit, `missing` is returned. +`overlayed` indicates if any matching method is defined in an overlayed method table. """ function findall(@nospecialize(sig::Type), table::InternalMethodTable; limit::Int=Int(typemax(Int32))) - return _findall(sig, nothing, table.world, limit) + result = _findall(sig, nothing, table.world, limit) + result === missing && return missing + return result, false end function findall(@nospecialize(sig::Type), table::OverlayMethodTable; limit::Int=Int(typemax(Int32))) @@ -57,7 +60,7 @@ function findall(@nospecialize(sig::Type), table::OverlayMethodTable; limit::Int nr = length(result) if nr ≥ 1 && result[nr].fully_covers # no need to fall back to the internal method table - return result + return result, true end # fall back to the internal method table fallback_result = _findall(sig, nothing, table.world, limit) @@ -68,7 +71,7 @@ function findall(@nospecialize(sig::Type), table::OverlayMethodTable; limit::Int WorldRange( max(result.valid_worlds.min_world, fallback_result.valid_worlds.min_world), min(result.valid_worlds.max_world, fallback_result.valid_worlds.max_world)), - result.ambig | fallback_result.ambig) + result.ambig | fallback_result.ambig), !isempty(result) end function _findall(@nospecialize(sig::Type), mt::Union{Nothing,Core.MethodTable}, world::UInt, limit::Int) @@ -83,31 +86,38 @@ function _findall(@nospecialize(sig::Type), mt::Union{Nothing,Core.MethodTable}, end """ - findsup(sig::Type, view::MethodTableView) -> Tuple{MethodMatch, WorldRange} or nothing - -Find the (unique) method `m` such that `sig <: m.sig`, while being more -specific than any other method with the same property. In other words, find -the method which is the least upper bound (supremum) under the specificity/subtype -relation of the queried `signature`. If `sig` is concrete, this is equivalent to -asking for the method that will be called given arguments whose types match the -given signature. This query is also used to implement `invoke`. - -Such a method `m` need not exist. It is possible that no method is an -upper bound of `sig`, or it is possible that among the upper bounds, there -is no least element. In both cases `nothing` is returned. + findsup(sig::Type, view::MethodTableView) -> + (match::MethodMatch, valid_worlds::WorldRange, overlayed::Bool) or nothing + +Find the (unique) method such that `sig <: match.method.sig`, while being more +specific than any other method with the same property. In other words, find the method +which is the least upper bound (supremum) under the specificity/subtype relation of +the queried `sig`nature. If `sig` is concrete, this is equivalent to asking for the method +that will be called given arguments whose types match the given signature. +Note that this query is also used to implement `invoke`. + +Such a matching method `match` doesn't necessarily exist. +It is possible that no method is an upper bound of `sig`, or +it is possible that among the upper bounds, there is no least element. +In both cases `nothing` is returned. + +`overlayed` indicates if the matching method is defined in an overlayed method table. """ function findsup(@nospecialize(sig::Type), table::InternalMethodTable) - return _findsup(sig, nothing, table.world) + return (_findsup(sig, nothing, table.world)..., false) end function findsup(@nospecialize(sig::Type), table::OverlayMethodTable) match, valid_worlds = _findsup(sig, table.mt, table.world) - match !== nothing && return match, valid_worlds + match !== nothing && return match, valid_worlds, true # fall back to the internal method table fallback_match, fallback_valid_worlds = _findsup(sig, nothing, table.world) - return fallback_match, WorldRange( - max(valid_worlds.min_world, fallback_valid_worlds.min_world), - min(valid_worlds.max_world, fallback_valid_worlds.max_world)) + return ( + fallback_match, + WorldRange( + max(valid_worlds.min_world, fallback_valid_worlds.min_world), + min(valid_worlds.max_world, fallback_valid_worlds.max_world)), + false) end function _findsup(@nospecialize(sig::Type), mt::Union{Nothing,Core.MethodTable}, world::UInt) diff --git a/base/compiler/ssair/show.jl b/base/compiler/ssair/show.jl index 1e98dda039040..76cbcbd4d5d7d 100644 --- a/base/compiler/ssair/show.jl +++ b/base/compiler/ssair/show.jl @@ -803,6 +803,7 @@ function Base.show(io::IO, e::Core.Compiler.Effects) print(io, ',') printstyled(io, string(tristate_letter(e.terminates), 't'); color=tristate_color(e.terminates)) print(io, ')') + e.overlayed && printstyled(io, '′'; color=:red) end @specialize diff --git a/base/compiler/tfuncs.jl b/base/compiler/tfuncs.jl index 54b89c9a04f43..25f26a20b115a 100644 --- a/base/compiler/tfuncs.jl +++ b/base/compiler/tfuncs.jl @@ -1756,11 +1756,11 @@ function builtin_effects(f::Builtin, argtypes::Vector{Any}, rt) if (f === Core.getfield || f === Core.isdefined) && length(argtypes) >= 3 # consistent if the argtype is immutable if isvarargtype(argtypes[2]) - return Effects(Effects(), effect_free=ALWAYS_TRUE, terminates=ALWAYS_TRUE) + return Effects(; effect_free=ALWAYS_TRUE, terminates=ALWAYS_TRUE, overlayed=false) end s = widenconst(argtypes[2]) if isType(s) || !isa(s, DataType) || isabstracttype(s) - return Effects(Effects(), effect_free=ALWAYS_TRUE, terminates=ALWAYS_TRUE) + return Effects(; effect_free=ALWAYS_TRUE, terminates=ALWAYS_TRUE, overlayed=false) end s = s::DataType ipo_consistent = !ismutabletype(s) @@ -1789,7 +1789,9 @@ function builtin_effects(f::Builtin, argtypes::Vector{Any}, rt) ipo_consistent ? ALWAYS_TRUE : ALWAYS_FALSE, effect_free ? ALWAYS_TRUE : ALWAYS_FALSE, nothrow ? ALWAYS_TRUE : TRISTATE_UNKNOWN, - ALWAYS_TRUE) + #=terminates=#ALWAYS_TRUE, + #=overlayed=#false, + ) end function builtin_nothrow(@nospecialize(f), argtypes::Array{Any, 1}, @nospecialize(rt)) @@ -1970,7 +1972,9 @@ function intrinsic_effects(f::IntrinsicFunction, argtypes::Vector{Any}) ipo_consistent ? ALWAYS_TRUE : ALWAYS_FALSE, effect_free ? ALWAYS_TRUE : ALWAYS_FALSE, nothrow ? ALWAYS_TRUE : TRISTATE_UNKNOWN, - ALWAYS_TRUE) + #=terminates=#ALWAYS_TRUE, + #=overlayed=#false, + ) end # TODO: this function is a very buggy and poor model of the return_type function diff --git a/base/compiler/typeinfer.jl b/base/compiler/typeinfer.jl index a047222cbfee0..1c54345b17de5 100644 --- a/base/compiler/typeinfer.jl +++ b/base/compiler/typeinfer.jl @@ -431,7 +431,7 @@ function rt_adjust_effects(@nospecialize(rt), ipo_effects::Effects) # but we don't currently model idempontency using dataflow, so we don't notice. # Fix that up here to improve precision. if !ipo_effects.inbounds_taints_consistency && rt === Union{} - return Effects(ipo_effects, consistent=ALWAYS_TRUE) + return Effects(ipo_effects; consistent=ALWAYS_TRUE) end return ipo_effects end @@ -755,11 +755,11 @@ function merge_call_chain!(parent::InferenceState, ancestor::InferenceState, chi # and ensure that walking the parent list will get the same result (DAG) from everywhere # Also taint the termination effect, because we can no longer guarantee the absence # of recursion. - tristate_merge!(parent, Effects(EFFECTS_TOTAL, terminates=TRISTATE_UNKNOWN)) + tristate_merge!(parent, Effects(EFFECTS_TOTAL; terminates=TRISTATE_UNKNOWN)) while true add_cycle_backedge!(child, parent, parent.currpc) union_caller_cycle!(ancestor, child) - tristate_merge!(child, Effects(EFFECTS_TOTAL, terminates=TRISTATE_UNKNOWN)) + tristate_merge!(child, Effects(EFFECTS_TOTAL; terminates=TRISTATE_UNKNOWN)) child = parent child === ancestor && break parent = child.parent::InferenceState diff --git a/base/compiler/types.jl b/base/compiler/types.jl index 65ce341dd55e1..282582c016d97 100644 --- a/base/compiler/types.jl +++ b/base/compiler/types.jl @@ -38,6 +38,7 @@ struct Effects effect_free::TriState nothrow::TriState terminates::TriState + overlayed::Bool # This effect is currently only tracked in inference and modified # :consistent before caching. We may want to track it in the future. inbounds_taints_consistency::Bool @@ -46,27 +47,33 @@ function Effects( consistent::TriState, effect_free::TriState, nothrow::TriState, - terminates::TriState) + terminates::TriState, + overlayed::Bool) return Effects( consistent, effect_free, nothrow, terminates, + overlayed, false) end -Effects() = Effects(TRISTATE_UNKNOWN, TRISTATE_UNKNOWN, TRISTATE_UNKNOWN, TRISTATE_UNKNOWN) -function Effects(e::Effects; +const EFFECTS_TOTAL = Effects(ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE, false) +const EFFECTS_UNKNOWN = Effects(TRISTATE_UNKNOWN, TRISTATE_UNKNOWN, TRISTATE_UNKNOWN, TRISTATE_UNKNOWN, true) + +function Effects(e::Effects = EFFECTS_UNKNOWN; consistent::TriState = e.consistent, effect_free::TriState = e.effect_free, nothrow::TriState = e.nothrow, terminates::TriState = e.terminates, + overlayed::Bool = e.overlayed, inbounds_taints_consistency::Bool = e.inbounds_taints_consistency) return Effects( consistent, effect_free, nothrow, terminates, + overlayed, inbounds_taints_consistency) end @@ -82,20 +89,20 @@ is_removable_if_unused(effects::Effects) = effects.terminates === ALWAYS_TRUE && effects.nothrow === ALWAYS_TRUE -const EFFECTS_TOTAL = Effects(ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE) - function encode_effects(e::Effects) - return e.consistent.state | - (e.effect_free.state << 2) | - (e.nothrow.state << 4) | - (e.terminates.state << 6) + return (e.consistent.state << 1) | + (e.effect_free.state << 3) | + (e.nothrow.state << 5) | + (e.terminates.state << 7) | + (e.overlayed) end function decode_effects(e::UInt8) return Effects( - TriState(e & 0x3), - TriState((e >> 2) & 0x3), - TriState((e >> 4) & 0x3), - TriState((e >> 6) & 0x3), + TriState((e >> 1) & 0x03), + TriState((e >> 3) & 0x03), + TriState((e >> 5) & 0x03), + TriState((e >> 7) & 0x03), + e & 0x01 ≠ 0x00, false) end @@ -109,6 +116,7 @@ function tristate_merge(old::Effects, new::Effects) old.nothrow, new.nothrow), tristate_merge( old.terminates, new.terminates), + old.overlayed | new.overlayed, old.inbounds_taints_consistency | new.inbounds_taints_consistency) end @@ -158,7 +166,7 @@ mutable struct InferenceResult arginfo#=::Union{Nothing,Tuple{ArgInfo,InferenceState}}=# = nothing) argtypes, overridden_by_const = matching_cache_argtypes(linfo, arginfo) return new(linfo, argtypes, overridden_by_const, Any, nothing, - WorldRange(), Effects(), Effects(), nothing) + WorldRange(), Effects(; overlayed=false), Effects(; overlayed=false), nothing) end end diff --git a/base/reflection.jl b/base/reflection.jl index 95fb81c8859d6..484dc8b586664 100644 --- a/base/reflection.jl +++ b/base/reflection.jl @@ -1291,11 +1291,12 @@ function code_typed_opaque_closure(@nospecialize(closure::Core.OpaqueClosure); end end -function return_types(@nospecialize(f), @nospecialize(types=default_tt(f)), interp=Core.Compiler.NativeInterpreter()) +function return_types(@nospecialize(f), @nospecialize(types=default_tt(f)); + world = get_world_counter(), + interp = Core.Compiler.NativeInterpreter(world)) ccall(:jl_is_in_pure_context, Bool, ()) && error("code reflection cannot be used from generated functions") types = to_tuple_type(types) rt = [] - world = get_world_counter() for match in _methods(f, types, -1, world)::Vector match = match::Core.MethodMatch meth = func_for_method_checked(match.method, types, match.sparams) diff --git a/test/compiler/AbstractInterpreter.jl b/test/compiler/AbstractInterpreter.jl index f1fe4b06dcb63..8d5a50112cbf9 100644 --- a/test/compiler/AbstractInterpreter.jl +++ b/test/compiler/AbstractInterpreter.jl @@ -41,25 +41,53 @@ import Base.Experimental: @MethodTable, @overlay @MethodTable(OverlayedMT) CC.method_table(interp::MTOverlayInterp) = CC.OverlayMethodTable(CC.get_world_counter(interp), OverlayedMT) -@overlay OverlayedMT sin(x::Float64) = 1 -@test Base.return_types((Int,), MTOverlayInterp()) do x - sin(x) -end == Any[Int] -@test Base.return_types((Any,), MTOverlayInterp()) do x - Base.@invoke sin(x::Float64) -end == Any[Int] +strangesin(x) = sin(x) +@overlay OverlayedMT strangesin(x::Float64) = iszero(x) ? nothing : cos(x) +@test Base.return_types((Float64,); interp=MTOverlayInterp()) do x + strangesin(x) +end |> only === Union{Float64,Nothing} +@test Base.return_types((Any,); interp=MTOverlayInterp()) do x + Base.@invoke strangesin(x::Float64) +end |> only === Union{Float64,Nothing} # fallback to the internal method table -@test Base.return_types((Int,), MTOverlayInterp()) do x +@test Base.return_types((Int,); interp=MTOverlayInterp()) do x cos(x) -end == Any[Float64] -@test Base.return_types((Any,), MTOverlayInterp()) do x +end |> only === Float64 +@test Base.return_types((Any,); interp=MTOverlayInterp()) do x Base.@invoke cos(x::Float64) -end == Any[Float64] +end |> only === Float64 # not fully covered overlay method match overlay_match(::Any) = nothing @overlay OverlayedMT overlay_match(::Int) = missing -@test Base.return_types((Any,), MTOverlayInterp()) do x +@test Base.return_types((Any,); interp=MTOverlayInterp()) do x overlay_match(x) -end == Any[Union{Nothing,Missing}] +end |> only === Union{Nothing,Missing} + +# partial pure/concrete evaluation +@test Base.return_types(; interp=MTOverlayInterp()) do + isbitstype(Int) ? nothing : missing +end |> only === Nothing +Base.@assume_effects :terminates_globally function issue41694(x) + res = 1 + 1 < x < 20 || throw("bad") + while x > 1 + res *= x + x -= 1 + end + return res +end +@test Base.return_types(; interp=MTOverlayInterp()) do + issue41694(3) == 6 ? nothing : missing +end |> only === Nothing + +# disable partial pure/concrete evaluation when tainted by any overlayed call +Base.@assume_effects :total totalcall(f, args...) = f(args...) +@test Base.return_types(; interp=MTOverlayInterp()) do + if totalcall(strangesin, 1.0) == cos(1.0) + return nothing + else + return missing + end +end |> only === Nothing