Skip to content

Commit

Permalink
Merge branch 'master' into pc/codlayer5
Browse files Browse the repository at this point in the history
  • Loading branch information
DilumAluthge authored Apr 13, 2022
2 parents 61a065f + 5808648 commit dbce521
Show file tree
Hide file tree
Showing 57 changed files with 675 additions and 714 deletions.
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ Library changes
now be called on a dictionary or set shared by arbitrary tasks provided that there are no
tasks mutating the dictionary or set ([#44534]).
* Predicate function negation `!f` now returns a composed function `(!) ∘ f` instead of an anonymous function ([#44752]).
* `RoundFromZero` now works for non-`BigFloat` types ([#41246]).


Standard library changes
Expand Down
7 changes: 1 addition & 6 deletions base/array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ const DenseVecOrMat{T} = Union{DenseVector{T}, DenseMatrix{T}}

## Basic functions ##

import Core: arraysize, arrayset, arrayref, const_arrayref
using Core: arraysize, arrayset, const_arrayref

vect() = Vector{Any}()
vect(X::T...) where {T} = T[ X[i] for i = 1:length(X) ]
Expand Down Expand Up @@ -212,7 +212,6 @@ function bitsunionsize(u::Union)
return sz
end

length(a::Array) = arraylen(a)
elsize(@nospecialize _::Type{A}) where {T,A<:Array{T}} = aligned_sizeof(T)
sizeof(a::Array) = Core.sizeof(a)

Expand Down Expand Up @@ -920,10 +919,6 @@ julia> getindex(A, "a")
"""
function getindex end

# This is more complicated than it needs to be in order to get Win64 through bootstrap
@eval getindex(A::Array, i1::Int) = arrayref($(Expr(:boundscheck)), A, i1)
@eval getindex(A::Array, i1::Int, i2::Int, I::Int...) = (@inline; arrayref($(Expr(:boundscheck)), A, i1, i2, I...))

# Faster contiguous indexing using copyto! for AbstractUnitRange and Colon
function getindex(A::Array, I::AbstractUnitRange{<:Integer})
@inline
Expand Down
67 changes: 42 additions & 25 deletions base/asyncevent.jl
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,22 @@ the async condition object itself.
"""
function AsyncCondition(cb::Function)
async = AsyncCondition()
t = @task while _trywait(async)
cb(async)
isopen(async) || return
t = @task begin
unpreserve_handle(async)
while _trywait(async)
cb(async)
isopen(async) || return
end
end
# here we are mimicking parts of _trywait, in coordination with task `t`
preserve_handle(async)
@lock async.cond begin
if async.set
schedule(t)
else
_wait2(async.cond, t)
end
end
lock(async.cond)
_wait2(async.cond, t)
unlock(async.cond)
return async
end

Expand Down Expand Up @@ -115,6 +124,7 @@ function _trywait(t::Union{Timer, AsyncCondition})
# full barrier now for AsyncCondition
t isa Timer || Core.Intrinsics.atomic_fence(:acquire_release)
else
t.isopen || return false
t.handle == C_NULL && return false
iolock_begin()
set = t.set
Expand All @@ -123,14 +133,12 @@ function _trywait(t::Union{Timer, AsyncCondition})
lock(t.cond)
try
set = t.set
if !set
if t.handle != C_NULL
iolock_end()
set = wait(t.cond)
unlock(t.cond)
iolock_begin()
lock(t.cond)
end
if !set && t.isopen && t.handle != C_NULL
iolock_end()
set = wait(t.cond)
unlock(t.cond)
iolock_begin()
lock(t.cond)
end
finally
unlock(t.cond)
Expand Down Expand Up @@ -266,19 +274,28 @@ julia> begin
"""
function Timer(cb::Function, timeout::Real; interval::Real=0.0)
timer = Timer(timeout, interval=interval)
t = @task while _trywait(timer)
try
cb(timer)
catch err
write(stderr, "Error in Timer:\n")
showerror(stderr, err, catch_backtrace())
return
t = @task begin
unpreserve_handle(timer)
while _trywait(timer)
try
cb(timer)
catch err
write(stderr, "Error in Timer:\n")
showerror(stderr, err, catch_backtrace())
return
end
isopen(timer) || return
end
end
# here we are mimicking parts of _trywait, in coordination with task `t`
preserve_handle(timer)
@lock timer.cond begin
if timer.set
schedule(t)
else
_wait2(timer.cond, t)
end
isopen(timer) || return
end
lock(timer.cond)
_wait2(timer.cond, t)
unlock(timer.cond)
return timer
end

Expand Down
9 changes: 5 additions & 4 deletions base/checked.jl
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,10 @@ function checked_abs end

function checked_abs(x::SignedInt)
r = ifelse(x<0, -x, x)
r<0 && throw(OverflowError(string("checked arithmetic: cannot compute |x| for x = ", x, "::", typeof(x))))
r
end
r<0 || return r
msg = LazyString("checked arithmetic: cannot compute |x| for x = ", x, "::", typeof(x))
throw(OverflowError(msg))
end
checked_abs(x::UnsignedInt) = x
checked_abs(x::Bool) = x

Expand Down Expand Up @@ -151,7 +152,7 @@ end


throw_overflowerr_binaryop(op, x, y) = (@noinline;
throw(OverflowError(Base.invokelatest(string, x, " ", op, " ", y, " overflowed for type ", typeof(x)))))
throw(OverflowError(LazyString(x, " ", op, " ", y, " overflowed for type ", typeof(x)))))

"""
Base.checked_add(x, y)
Expand Down
5 changes: 3 additions & 2 deletions base/compiler/typeinfer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -838,8 +838,9 @@ function typeinf_edge(interp::AbstractInterpreter, method::Method, @nospecialize
code = get(code_cache(interp), mi, nothing)
if code isa CodeInstance # return existing rettype if the code is already inferred
if code.inferred === nothing && is_stmt_inline(get_curr_ssaflag(caller))
# we already inferred this edge previously and decided to discarded the inferred code
# but the inlinear will request to use it, we re-infer it here and keep it around in the local cache
# we already inferred this edge before and decided to discard the inferred code,
# nevertheless we re-infer it here again and keep it around in the local cache
# since the inliner will request to use it later
cache = :local
else
effects = ipo_effects(code)
Expand Down
28 changes: 27 additions & 1 deletion base/div.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ without any intermediate rounding.
See also [`fld`](@ref) and [`cld`](@ref), which are special cases of this function.
!!! compat "Julia 1.9"
`RoundFromZero` requires at least Julia 1.9.
# Examples:
```jldoctest
julia> div(4, 3, RoundDown) # Matches fld(4, 3)
Expand All @@ -33,6 +36,10 @@ julia> div(-5, 2, RoundNearestTiesAway)
-3
julia> div(-5, 2, RoundNearestTiesUp)
-2
julia> div(4, 3, RoundFromZero)
2
julia> div(-4, 3, RoundFromZero)
-2
```
"""
div(x, y, r::RoundingMode)
Expand Down Expand Up @@ -63,6 +70,13 @@ without any intermediate rounding.
`[0,-y)` otherwise. The result may not be exact if `x` and `y` have the same sign, and
`abs(x) < abs(y)`. See also [`RoundUp`](@ref).
- if `r == RoundFromZero`, then the result is in the interval `(-y, 0]` if `y` is positive, or
`[0, -y)` otherwise. The result may not be exact if `x` and `y` have the same sign, and
`abs(x) < abs(y)`. See also [`RoundFromZero`](@ref).
!!! compat "Julia 1.9"
`RoundFromZero` requires at least Julia 1.9.
# Examples:
```jldoctest
julia> x = 9; y = 4;
Expand All @@ -86,6 +100,10 @@ rem(x, y, ::RoundingMode{:Up}) = mod(x, -y)
rem(x, y, r::RoundingMode{:Nearest}) = x - y*div(x, y, r)
rem(x::Integer, y::Integer, r::RoundingMode{:Nearest}) = divrem(x, y, r)[2]

function rem(x, y, ::typeof(RoundFromZero))
signbit(x) == signbit(y) ? rem(x, y, RoundUp) : rem(x, y, RoundDown)
end

"""
fld(x, y)
Expand Down Expand Up @@ -240,6 +258,10 @@ function divrem(x::Integer, y::Integer, rnd::typeof(RoundNearestTiesUp))
end
end

function divrem(x, y, ::typeof(RoundFromZero))
signbit(x) == signbit(y) ? divrem(x, y, RoundUp) : divrem(x, y, RoundDown)
end

"""
fldmod(x, y)
Expand Down Expand Up @@ -276,12 +298,16 @@ function div(x::Integer, y::Integer, rnd::Union{typeof(RoundNearest),
divrem(x, y, rnd)[1]
end

function div(x::Integer, y::Integer, ::typeof(RoundFromZero))
signbit(x) == signbit(y) ? div(x, y, RoundUp) : div(x, y, RoundDown)
end

# For bootstrapping purposes, we define div for integers directly. Provide the
# generic signature also
div(a::T, b::T, ::typeof(RoundToZero)) where {T<:Union{BitSigned, BitUnsigned64}} = div(a, b)
div(a::Bool, b::Bool, r::RoundingMode) = div(a, b)
# Prevent ambiguities
for rm in (RoundUp, RoundDown, RoundToZero)
for rm in (RoundUp, RoundDown, RoundToZero, RoundFromZero)
@eval div(a::Bool, b::Bool, r::$(typeof(rm))) = div(a, b)
end
function div(x::Bool, y::Bool, rnd::Union{typeof(RoundNearest),
Expand Down
51 changes: 45 additions & 6 deletions base/essentials.jl
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license

using Core: CodeInfo, SimpleVector, donotdelete
using Core: CodeInfo, SimpleVector, donotdelete, arrayref

const Callable = Union{Function,Type}

const Bottom = Union{}

# Define minimal array interface here to help code used in macros:
length(a::Array) = arraylen(a)

# This is more complicated than it needs to be in order to get Win64 through bootstrap
eval(:(getindex(A::Array, i1::Int) = arrayref($(Expr(:boundscheck)), A, i1)))
eval(:(getindex(A::Array, i1::Int, i2::Int, I::Int...) = (@inline; arrayref($(Expr(:boundscheck)), A, i1, i2, I...))))

"""
AbstractSet{T}
Expand Down Expand Up @@ -54,12 +61,12 @@ end
@nospecialize
Applied to a function argument name, hints to the compiler that the method
should not be specialized for different types of that argument,
but instead to use precisely the declared type for each argument.
This is only a hint for avoiding excess code generation.
Can be applied to an argument within a formal argument list,
implementation should not be specialized for different types of that argument,
but instead use the declared type for that argument.
It can be applied to an argument within a formal argument list,
or in the function body.
When applied to an argument, the macro must wrap the entire argument expression.
When applied to an argument, the macro must wrap the entire argument expression, e.g.,
`@nospecialize(x::Real)` or `@nospecialize(i::Integer...)` rather than wrapping just the argument name.
When used in a function body, the macro must occur in statement position and
before any code.
Expand Down Expand Up @@ -87,6 +94,38 @@ end
f(y) = [x for x in y]
@specialize
```
!!! note
`@nospecialize` affects code generation but not inference: it limits the diversity
of the resulting native code, but it does not impose any limitations (beyond the
standard ones) on type-inference.
# Example
```julia
julia> f(A::AbstractArray) = g(A)
f (generic function with 1 method)
julia> @noinline g(@nospecialize(A::AbstractArray)) = A[1]
g (generic function with 1 method)
julia> @code_typed f([1.0])
CodeInfo(
1 ─ %1 = invoke Main.g(_2::AbstractArray)::Float64
└── return %1
) => Float64
```
Here, the `@nospecialize` annotation results in the equivalent of
```julia
f(A::AbstractArray) = invoke(g, Tuple{AbstractArray}, A)
```
ensuring that only one version of native code will be generated for `g`,
one that is generic for any `AbstractArray`.
However, the specific return type is still inferred for both `g` and `f`,
and this is still used in optimizing the callers of `f` and `g`.
"""
macro nospecialize(vars...)
if nfields(vars) === 1
Expand Down
4 changes: 4 additions & 0 deletions base/expr.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license

isexpr(@nospecialize(ex), heads) = isa(ex, Expr) && in(ex.head, heads)
isexpr(@nospecialize(ex), heads, n::Int) = isa(ex, Expr) && in(ex.head, heads) && length(ex.args) == n
const is_expr = isexpr

## symbols ##

"""
Expand Down
4 changes: 4 additions & 0 deletions base/floatfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,10 @@ function round(x::T, ::RoundingMode{:NearestTiesUp}) where {T <: AbstractFloat}
copysign(floor((x + (T(0.25) - eps(T(0.5)))) + (T(0.25) + eps(T(0.5)))), x)
end

function Base.round(x::AbstractFloat, ::typeof(RoundFromZero))
signbit(x) ? round(x, RoundDown) : round(x, RoundUp)
end

# isapprox: approximate equality of numbers
"""
isapprox(x, y; atol::Real=0, rtol::Real=atol>0 ? 0 : √eps, nans::Bool=false[, norm::Function])
Expand Down
3 changes: 2 additions & 1 deletion base/intfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ function gcd(a::T, b::T) where T<:BitInteger
signbit(r) && __throw_gcd_overflow(a, b)
return r
end
@noinline __throw_gcd_overflow(a, b) = throw(OverflowError("gcd($a, $b) overflows"))
@noinline __throw_gcd_overflow(a, b) =
throw(OverflowError(LazyString("gcd(", a, ", ", b, ") overflows")))

# binary GCD (aka Stein's) algorithm
# about 1.7x (2.1x) faster for random Int64s (Int128s)
Expand Down
3 changes: 1 addition & 2 deletions base/meta.jl
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,7 @@ julia> Meta.isexpr(ex, :call, 2)
true
```
"""
isexpr(@nospecialize(ex), heads) = isa(ex, Expr) && in(ex.head, heads)
isexpr(@nospecialize(ex), heads, n::Int) = isa(ex, Expr) && in(ex.head, heads) && length(ex.args) == n
isexpr

"""
replace_sourceloc!(location, expr)
Expand Down
8 changes: 4 additions & 4 deletions base/range.jl
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ be an `Integer`.
```jldoctest
julia> LinRange(1.5, 5.5, 9)
9-element LinRange{Float64, Int64}:
1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,5.5
1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5
```
Compared to using [`range`](@ref), directly constructing a `LinRange` should
Expand Down Expand Up @@ -592,7 +592,7 @@ as if it were `collect(r)`, dependent on the size of the
terminal, and taking into account whether compact numbers should be shown.
It figures out the width in characters of each element, and if they
end up too wide, it shows the first and last elements separated by a
horizontal ellipsis. Typical output will look like `1.0,2.0,3.0,…,4.0,5.0,6.0`.
horizontal ellipsis. Typical output will look like `1.0, 2.0, …, 5.0, 6.0`.
`print_range(io, r, pre, sep, post, hdots)` uses optional
parameters `pre` and `post` characters for each printed row,
Expand All @@ -601,9 +601,9 @@ parameters `pre` and `post` characters for each printed row,
"""
function print_range(io::IO, r::AbstractRange,
pre::AbstractString = " ",
sep::AbstractString = ",",
sep::AbstractString = ", ",
post::AbstractString = "",
hdots::AbstractString = ",\u2026,") # horiz ellipsis
hdots::AbstractString = ", \u2026, ") # horiz ellipsis
# This function borrows from print_matrix() in show.jl
# and should be called by show and display
sz = displaysize(io)
Expand Down
Loading

0 comments on commit dbce521

Please sign in to comment.