Skip to content

Commit 381eac3

Browse files
authored
Merge pull request #45491 from JuliaLang/backports-release-1.8
Backports for 1.8-rc2/1.8.0
2 parents 6368fdc + 7a23871 commit 381eac3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+1065
-946
lines changed

Make.inc

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -900,10 +900,6 @@ OPENBLAS_DYNAMIC_ARCH:=0
900900
OPENBLAS_TARGET_ARCH:=ARMV8
901901
USE_BLAS64:=1
902902
BINARY:=64
903-
ifeq ($(OS),Darwin)
904-
# Apple Chips are all at least A12Z
905-
MCPU:=apple-a12
906-
endif
907903
endif
908904

909905
# Set MARCH-specific flags

NEWS.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ New language features
1111
e.g. `[;;;]` creates a 0×0×0 `Array` ([#41618]).
1212
* `try`-blocks can now optionally have an `else`-block which is executed right after the main body only if
1313
no errors were thrown ([#42211]).
14-
* `@inline` and `@noinline` annotations can now be placed within a function body ([#41312]).
15-
* `@inline` and `@noinline` annotations can now be applied to a function call site or block
14+
* `@inline` and `@noinline` can now be placed within a function body, allowing one to annotate anonymous function ([#41312]).
15+
* `@inline` and `@noinline` can now be applied to a function at callsite or block
1616
to enforce the involved function calls to be (or not to be) inlined ([#41328]).
1717
* ``, ``, and `` are now allowed as identifier characters ([#42314]).
1818
* Support for Unicode 14.0.0 ([#43443]).
@@ -43,7 +43,9 @@ Compiler/Runtime improvements
4343
`libjulia-codegen`. It is loaded by default, so normal usage should see no changes.
4444
In deployments that do not need the compiler (e.g. system images where all needed code
4545
is precompiled), this library (and its LLVM dependency) can simply be excluded ([#41936]).
46-
* Conditional type constraints can now be forwarded interprocedurally (i.e. propagated from caller to callee) ([#42529]).
46+
* Conditional type constraints are now be forwarded interprocedurally (i.e. propagated from caller to callee).
47+
This allows inference to understand e.g. `Base.ifelse(isa(x, Int), x, 0)` returns `::Int`-value
48+
even if the type of `x` is not known ([#42529]).
4749
* Julia-level SROA (Scalar Replacement of Aggregates) has been improved: allowing elimination of
4850
`getfield` calls with constant global fields ([#42355]), enabling elimination of mutable structs with
4951
uninitialized fields ([#43208]), improving performance ([#43232]), and handling more nested `getfield`
@@ -53,7 +55,7 @@ Compiler/Runtime improvements
5355
* Inference now tracks various effects such as side-effectful-ness and nothrow-ness on a per-specialization basis.
5456
Code heavily dependent on constant propagation should see significant compile-time performance improvements and
5557
certain cases (e.g. calls to uninlinable functions that are nevertheless effect free) should see runtime performance
56-
improvements. Effects may be overwritten manually with the `@Base.assume_effects` macro ([#43852]).
58+
improvements. Effects may be overwritten manually with the `Base.@assume_effects` macro ([#43852]).
5759
* Precompilation (with explicit `precompile` directives or representative workloads) now saves more type-inferred code,
5860
resulting in reduced time-to-first task for packages that use precompilation. This change also eliminates the
5961
runtime performance degradation occasionally triggered by precompilation on older Julia versions. More specifically,
@@ -108,6 +110,8 @@ New library features
108110
* TCP socket objects now expose `closewrite` functionality and support half-open mode usage ([#40783]).
109111
* `extrema` now accepts an `init` keyword argument ([#36265], [#43604]).
110112
* `Iterators.countfrom` now accepts any type that defines `+` ([#37747]).
113+
* `@time` now separates out % time spent recompiling invalidated methods ([#45015]).
114+
* `@time_imports` now shows any compilation and recompilation time percentages per import ([#45064]).
111115

112116
Standard library changes
113117
------------------------

base/abstractarray.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2478,7 +2478,7 @@ function _typed_hvncat_shape(::Type{T}, shape::NTuple{N, Tuple}, row_first, as::
24782478
shapelength == lengthas || throw(ArgumentError("number of elements does not match shape; expected $(shapelength), got $lengthas)"))
24792479
# discover dimensions
24802480
nd = max(N, cat_ndims(as[1]))
2481-
outdims = zeros(Int, nd)
2481+
outdims = fill(-1, nd)
24822482
currentdims = zeros(Int, nd)
24832483
blockcounts = zeros(Int, nd)
24842484
shapepos = ones(Int, nd)
@@ -2503,7 +2503,7 @@ function _typed_hvncat_shape(::Type{T}, shape::NTuple{N, Tuple}, row_first, as::
25032503

25042504
isendblock = blockcounts[d] == shapev[d][shapepos[d]]
25052505
if isendblock
2506-
if outdims[d] == 0
2506+
if outdims[d] == -1
25072507
outdims[d] = currentdims[d]
25082508
elseif outdims[d] != currentdims[d]
25092509
throw(ArgumentError("argument $i has a mismatched number of elements along axis $ad; \

base/compiler/abstractinterpretation.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -720,7 +720,7 @@ function concrete_eval_eligible(interp::AbstractInterpreter,
720720
isoverlayed(method_table(interp)) && !is_nonoverlayed(result.edge_effects) && return false
721721
return f !== nothing &&
722722
result.edge !== nothing &&
723-
is_concrete_eval_eligible(result.edge_effects) &&
723+
is_foldable(result.edge_effects) &&
724724
is_all_const_arg(arginfo)
725725
end
726726

base/compiler/ssair/inlining.jl

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,11 +1257,7 @@ function handle_const_call!(
12571257
result = results[j]
12581258
if isa(result, ConstResult)
12591259
case = const_result_item(result, state)
1260-
if case === nothing
1261-
fully_covered = false
1262-
else
1263-
push!(cases, InliningCase(result.mi.specTypes, case))
1264-
end
1260+
push!(cases, InliningCase(result.mi.specTypes, case))
12651261
elseif isa(result, InferenceResult)
12661262
fully_covered &= handle_inf_result!(result, argtypes, flag, state, cases)
12671263
else
@@ -1314,7 +1310,9 @@ end
13141310

13151311
function const_result_item(result::ConstResult, state::InliningState)
13161312
if !isdefined(result, :result) || !is_inlineable_constant(result.result)
1317-
return compileable_specialization(state.et, result.mi, result.effects)
1313+
case = compileable_specialization(state.et, result.mi, result.effects)
1314+
@assert case !== nothing "concrete evaluation should never happen for uncompileable callsite"
1315+
return case
13181316
end
13191317
@assert result.effects === EFFECTS_TOTAL
13201318
return ConstantCase(quoted(result.result))

base/compiler/tfuncs.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1515,6 +1515,10 @@ function tuple_tfunc(argtypes::Vector{Any})
15151515
params[i] = typeof(x.val)
15161516
else
15171517
x = isvarargtype(x) ? x : widenconst(x)
1518+
# since there don't exist any values whose runtime type are `Tuple{Type{...}}`,
1519+
# here we should turn such `Type{...}`-parameters to valid parameters, e.g.
1520+
# (::Type{Int},) -> Tuple{DataType} (or PartialStruct for more accuracy)
1521+
# (::Union{Type{Int32},Type{Int64}}) -> Tuple{Type}
15181522
if isType(x)
15191523
anyinfo = true
15201524
xparam = x.parameters[1]
@@ -1523,6 +1527,10 @@ function tuple_tfunc(argtypes::Vector{Any})
15231527
else
15241528
params[i] = Type
15251529
end
1530+
elseif iskindtype(x)
1531+
params[i] = x
1532+
elseif !isvarargtype(x) && hasintersect(x, Type)
1533+
params[i] = Union{x, Type}
15261534
else
15271535
params[i] = x
15281536
end

base/compiler/types.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,13 +113,13 @@ is_nothrow(effects::Effects) = effects.nothrow === ALWAYS_TRUE
113113
is_terminates(effects::Effects) = effects.terminates === ALWAYS_TRUE
114114
is_nonoverlayed(effects::Effects) = effects.nonoverlayed
115115

116-
is_concrete_eval_eligible(effects::Effects) =
116+
is_foldable(effects::Effects) =
117117
is_consistent(effects) &&
118118
is_effect_free(effects) &&
119119
is_terminates(effects)
120120

121121
is_total(effects::Effects) =
122-
is_concrete_eval_eligible(effects) &&
122+
is_foldable(effects) &&
123123
is_nothrow(effects)
124124

125125
is_removable_if_unused(effects::Effects) =

base/essentials.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -766,7 +766,7 @@ function invoke_in_world(world::UInt, @nospecialize(f), @nospecialize args...; k
766766
end
767767

768768
# TODO: possibly make this an intrinsic
769-
inferencebarrier(@nospecialize(x)) = Ref{Any}(x)[]
769+
inferencebarrier(@nospecialize(x)) = RefValue{Any}(x).x
770770

771771
"""
772772
isempty(collection) -> Bool

base/expr.jl

Lines changed: 74 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,9 @@ end
381381
`@assume_effects` overrides the compiler's effect modeling for the given method.
382382
`ex` must be a method definition or `@ccall` expression.
383383
384+
!!! compat "Julia 1.8"
385+
Using `Base.@assume_effects` requires Julia version 1.8.
386+
384387
```jldoctest
385388
julia> Base.@assume_effects :terminates_locally function pow(x)
386389
# this :terminates_locally allows `pow` to be constant-folded
@@ -402,7 +405,7 @@ julia> code_typed() do
402405
1 ─ return 479001600
403406
) => Int64
404407
405-
julia> Base.@assume_effects :total_may_throw @ccall jl_type_intersection(Vector{Int}::Any, Vector{<:Integer}::Any)::Any
408+
julia> Base.@assume_effects :total !:nothrow @ccall jl_type_intersection(Vector{Int}::Any, Vector{<:Integer}::Any)::Any
406409
Vector{Int64} (alias for Array{Int64, 1})
407410
```
408411
@@ -423,12 +426,15 @@ The following `setting`s are supported.
423426
- `:nothrow`
424427
- `:terminates_globally`
425428
- `:terminates_locally`
429+
- `:foldable`
426430
- `:total`
427431
432+
# Extended help
433+
428434
---
429-
# `:consistent`
435+
## `:consistent`
430436
431-
The `:consistent` setting asserts that for egal inputs:
437+
The `:consistent` setting asserts that for egal (`===`) inputs:
432438
- The manner of termination (return value, exception, non-termination) will always be the same.
433439
- If the method returns, the results will always be egal.
434440
@@ -461,7 +467,7 @@ The `:consistent` setting asserts that for egal inputs:
461467
itself is not required to meet the egality requirement specified above.
462468
463469
---
464-
# `:effect_free`
470+
## `:effect_free`
465471
466472
The `:effect_free` setting asserts that the method is free of externally semantically
467473
visible side effects. The following is an incomplete list of externally semantically
@@ -491,7 +497,7 @@ were not executed.
491497
valid for all world ages and limit use of this assertion accordingly.
492498
493499
---
494-
# `:nothrow`
500+
## `:nothrow`
495501
496502
The `:nothrow` settings asserts that this method does not terminate abnormally
497503
(i.e. will either always return a value or never return).
@@ -505,7 +511,7 @@ The `:nothrow` settings asserts that this method does not terminate abnormally
505511
`MethodErrors` and similar exceptions count as abnormal termination.
506512
507513
---
508-
# `:terminates_globally`
514+
## `:terminates_globally`
509515
510516
The `:terminates_globally` settings asserts that this method will eventually terminate
511517
(either normally or abnormally), i.e. does not loop indefinitely.
@@ -520,7 +526,7 @@ The `:terminates_globally` settings asserts that this method will eventually ter
520526
on a method that *technically*, but not *practically*, terminates.
521527
522528
---
523-
# `:terminates_locally`
529+
## `:terminates_locally`
524530
525531
The `:terminates_locally` setting is like `:terminates_globally`, except that it only
526532
applies to syntactic control flow *within* the annotated method. It is thus
@@ -531,59 +537,79 @@ non-termination if the method calls some other method that does not terminate.
531537
`:terminates_globally` implies `:terminates_locally`.
532538
533539
---
534-
# `:total`
540+
## `:foldable`
541+
542+
This setting is a convenient shortcut for the set of effects that the compiler
543+
requires to be guaranteed to constant fold a call at compile time. It is
544+
currently equivalent to the following `setting`s:
535545
536-
This `setting` combines the following other assertions:
537546
- `:consistent`
538547
- `:effect_free`
539-
- `:nothrow`
540548
- `:terminates_globally`
541-
and is a convenient shortcut.
549+
550+
!!! note
551+
This list in particular does not include `:nothrow`. The compiler will still
552+
attempt constant propagation and note any thrown error at compile time. Note
553+
however, that by the `:consistent`-cy requirements, any such annotated call
554+
must consistently throw given the same argument values.
542555
543556
---
544-
# `:total_may_throw`
557+
## `:total`
545558
546-
This `setting` combines the following other assertions:
559+
This `setting` is the maximum possible set of effects. It currently implies
560+
the following other `setting`s:
547561
- `:consistent`
548562
- `:effect_free`
563+
- `:nothrow`
549564
- `:terminates_globally`
550-
and is a convenient shortcut.
551565
552-
!!! note
553-
This setting is particularly useful since it allows the compiler to evaluate a call of
554-
the applied method when all the call arguments are fully known to be constant, no matter
555-
if the call results in an error or not.
556-
557-
`@assume_effects :total_may_throw` is similar to [`@pure`](@ref) with the primary
558-
distinction that the `:consistent`-cy requirement applies world-age wise rather
559-
than globally as described above. However, in particular, a method annotated
560-
`@pure` should always be `:total` or `:total_may_throw`.
561-
Another advantage is that effects introduced by `@assume_effects` are propagated to
562-
callers interprocedurally while a purity defined by `@pure` is not.
566+
!!! warning
567+
`:total` is a very strong assertion and will likely gain additional semantics
568+
in future versions of Julia (e.g. if additional effects are added and included
569+
in the definition of `:total`). As a result, it should be used with care.
570+
Whenever possible, prefer to use the minimum possible set of specific effect
571+
assertions required for a particular application. In cases where a large
572+
number of effect overrides apply to a set of functions, a custom macro is
573+
recommended over the use of `:total`.
574+
575+
---
576+
## Negated effects
577+
578+
Effect names may be prefixed by `!` to indicate that the effect should be removed
579+
from an earlier meta effect. For example, `:total !:nothrow` indicates that while
580+
the call is generally total, it may however throw.
581+
582+
---
583+
## Comparison to `@pure`
584+
585+
`@assume_effects :foldable` is similar to [`@pure`](@ref) with the primary
586+
distinction that the `:consistent`-cy requirement applies world-age wise rather
587+
than globally as described above. However, in particular, a method annotated
588+
`@pure` should always be at least `:foldable`.
589+
Another advantage is that effects introduced by `@assume_effects` are propagated to
590+
callers interprocedurally while a purity defined by `@pure` is not.
563591
"""
564592
macro assume_effects(args...)
565593
(consistent, effect_free, nothrow, terminates_globally, terminates_locally) =
566594
(false, false, false, false, false, false)
567-
for setting in args[1:end-1]
568-
if isa(setting, QuoteNode)
569-
setting = setting.value
570-
end
595+
for org_setting in args[1:end-1]
596+
(setting, val) = compute_assumed_setting(org_setting)
571597
if setting === :consistent
572-
consistent = true
598+
consistent = val
573599
elseif setting === :effect_free
574-
effect_free = true
600+
effect_free = val
575601
elseif setting === :nothrow
576-
nothrow = true
602+
nothrow = val
577603
elseif setting === :terminates_globally
578-
terminates_globally = true
604+
terminates_globally = val
579605
elseif setting === :terminates_locally
580-
terminates_locally = true
606+
terminates_locally = val
607+
elseif setting === :foldable
608+
consistent = effect_free = terminates_globally = val
581609
elseif setting === :total
582-
consistent = effect_free = nothrow = terminates_globally = true
583-
elseif setting === :total_may_throw
584-
consistent = effect_free = terminates_globally = true
610+
consistent = effect_free = nothrow = terminates_globally = val
585611
else
586-
throw(ArgumentError("@assume_effects $setting not supported"))
612+
throw(ArgumentError("@assume_effects $org_setting not supported"))
587613
end
588614
end
589615
ex = args[end]
@@ -598,6 +624,16 @@ macro assume_effects(args...)
598624
return esc(pushmeta!(ex, :purity, consistent, effect_free, nothrow, terminates_globally, terminates_locally))
599625
end
600626

627+
function compute_assumed_setting(@nospecialize(setting), val::Bool=true)
628+
if isexpr(setting, :call) && setting.args[1] === :(!)
629+
return compute_assumed_setting(setting.args[2], !val)
630+
elseif isa(setting, QuoteNode)
631+
return compute_assumed_setting(setting.value, val)
632+
else
633+
return (setting, val)
634+
end
635+
end
636+
601637
"""
602638
@propagate_inbounds
603639

base/fastmath.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,8 +279,8 @@ exp10_fast(x::Union{Float32,Float64}) = Base.Math.exp10_fast(x)
279279

280280
# builtins
281281

282-
pow_fast(x::Float32, y::Integer) = ccall("llvm.powi.f32", llvmcall, Float32, (Float32, Int32), x, y)
283-
pow_fast(x::Float64, y::Integer) = ccall("llvm.powi.f64", llvmcall, Float64, (Float64, Int32), x, y)
282+
pow_fast(x::Float32, y::Integer) = ccall("llvm.powi.f32.i32", llvmcall, Float32, (Float32, Int32), x, y)
283+
pow_fast(x::Float64, y::Integer) = ccall("llvm.powi.f64.i32", llvmcall, Float64, (Float64, Int32), x, y)
284284
pow_fast(x::FloatTypes, ::Val{p}) where {p} = pow_fast(x, p) # inlines already via llvm.powi
285285
@inline pow_fast(x, v::Val) = Base.literal_pow(^, x, v)
286286

0 commit comments

Comments
 (0)