Skip to content

Commit de7b9bc

Browse files
authored
Merge branch 'master' into extrema
2 parents 793a020 + bf3ed57 commit de7b9bc

File tree

136 files changed

+1098
-1247
lines changed

Some content is hidden

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

136 files changed

+1098
-1247
lines changed

NEWS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Compiler/Runtime improvements
1717
* All platforms can now use `@executable_path` within `jl_load_dynamic_library()`.
1818
This allows executable-relative paths to be embedded within executables on all
1919
platforms, not just MacOS, which the syntax is borrowed from. ([#35627])
20+
* Constant propogation now occurs through keyword arguments ([#35976])
2021

2122
Command-line option changes
2223
---------------------------
@@ -48,6 +49,8 @@ Standard library changes
4849
* `view`, `@view`, and `@views` now work on `AbstractString`s, returning a `SubString` when appropriate ([#35879]).
4950
* All `AbstractUnitRange{<:Integer}`s now work with `SubString`, `view`, `@view` and `@views` on strings ([#35879]).
5051
* `sum`, `prod`, `maximum`, `minimum`, and `extrema` now support `init` keyword argument ([#36188], [#35839], [#36265]).
52+
* `unique(f, itr; seen=Set{T}())` now allows you to declare the container type used for
53+
keeping track of values returned by `f` on elements of `itr` ([#36280]).
5154

5255
#### LinearAlgebra
5356
* New method `LinearAlgebra.issuccess(::CholeskyPivoted)` for checking whether pivoted Cholesky factorization was successful ([#36002]).

base/abstractarray.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1509,7 +1509,7 @@ _cat(dims, X...) = cat_t(promote_eltypeof(X...), X...; dims=dims)
15091509
catdims = dims2cat(dims)
15101510
shape = cat_shape(catdims, (), map(cat_size, X)...)
15111511
A = cat_similar(X[1], T, shape)
1512-
if T <: Number && count(!iszero, catdims) > 1
1512+
if count(!iszero, catdims) > 1
15131513
fill!(A, zero(T))
15141514
end
15151515
return __cat(A, shape, catdims, X...)

base/abstractarraymath.jl

Lines changed: 117 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -270,30 +270,8 @@ julia> repeat([1, 2, 3], 2, 3)
270270
3 3 3
271271
```
272272
"""
273-
repeat(a::AbstractArray, counts::Integer...) = repeat(a, outer = counts)
274-
275-
function repeat(a::AbstractVecOrMat, m::Integer, n::Integer=1)
276-
o, p = size(a,1), size(a,2)
277-
b = similar(a, o*m, p*n)
278-
for j=1:n
279-
d = (j-1)*p+1
280-
R = d:d+p-1
281-
for i=1:m
282-
c = (i-1)*o+1
283-
b[c:c+o-1, R] = a
284-
end
285-
end
286-
return b
287-
end
288-
289-
function repeat(a::AbstractVector, m::Integer)
290-
o = length(a)
291-
b = similar(a, o*m)
292-
for i=1:m
293-
c = (i-1)*o+1
294-
b[c:c+o-1] = a
295-
end
296-
return b
273+
function repeat(A::AbstractArray, counts...)
274+
return _RepeatInnerOuter.repeat(A, outer=counts)
297275
end
298276

299277
"""
@@ -330,89 +308,134 @@ julia> repeat([1 2; 3 4], inner=(2, 1), outer=(1, 3))
330308
```
331309
"""
332310
function repeat(A::AbstractArray; inner = nothing, outer = nothing)
333-
return _repeat_inner_outer(A, inner, outer)
311+
return _RepeatInnerOuter.repeat(A, inner=inner, outer=outer)
312+
end
313+
314+
module _RepeatInnerOuter
315+
316+
function repeat(arr; inner=nothing, outer=nothing)
317+
check(arr, inner, outer)
318+
arr, inner, outer = resolve(arr, inner, outer)
319+
repeat_inner_outer(arr, inner, outer)
320+
end
321+
322+
to_tuple(t::Tuple) = t
323+
to_tuple(x::Integer) = (x,)
324+
to_tuple(itr) = tuple(itr...)
325+
326+
function pad(a, b)
327+
N = max(length(a), length(b))
328+
Base.fill_to_length(a, 1, Val(N)), Base.fill_to_length(b, 1, Val(N))
329+
end
330+
function pad(a, b, c)
331+
N = max(max(length(a), length(b)), length(c))
332+
Base.fill_to_length(a, 1, Val(N)), Base.fill_to_length(b, 1, Val(N)), Base.fill_to_length(c, 1, Val(N))
333+
end
334+
335+
function resolve(arr::AbstractArray{<:Any, N}, inner::NTuple{N, Any}, outer::NTuple{N,Any}) where {N}
336+
arr, inner, outer
337+
end
338+
function resolve(arr, inner, outer)
339+
dims, inner, outer = pad(size(arr), to_tuple(inner), to_tuple(outer))
340+
reshape(arr, dims), inner, outer
341+
end
342+
function resolve(arr, inner::Nothing, outer::Nothing)
343+
return arr, inner, outer
344+
end
345+
function resolve(arr, inner::Nothing, outer)
346+
dims, outer = pad(size(arr), to_tuple(outer))
347+
reshape(arr, dims), inner, outer
348+
end
349+
function resolve(arr, inner, outer::Nothing)
350+
dims, inner = pad(size(arr), to_tuple(inner))
351+
reshape(arr, dims), inner, outer
334352
end
335353

336-
# we have optimized implementations of these cases above
337-
_repeat_inner_outer(A::AbstractVecOrMat, ::Nothing, r::Union{Tuple{Integer},Tuple{Integer,Integer}}) = repeat(A, r...)
338-
_repeat_inner_outer(A::AbstractVecOrMat, ::Nothing, r::Integer) = repeat(A, r)
339-
340-
_repeat_inner_outer(A, ::Nothing, ::Nothing) = A
341-
_repeat_inner_outer(A, ::Nothing, outer) = _repeat(A, ntuple(n->1, Val(ndims(A))), rep_kw2tup(outer))
342-
_repeat_inner_outer(A, inner, ::Nothing) = _repeat(A, rep_kw2tup(inner), ntuple(n->1, Val(ndims(A))))
343-
_repeat_inner_outer(A, inner, outer) = _repeat(A, rep_kw2tup(inner), rep_kw2tup(outer))
344-
345-
rep_kw2tup(n::Integer) = (n,)
346-
rep_kw2tup(v::AbstractArray{<:Integer}) = (v...,)
347-
rep_kw2tup(t::Tuple) = t
348-
349-
rep_shapes(A, i, o) = _rshps((), (), size(A), i, o)
350-
351-
_rshps(shp, shp_i, ::Tuple{}, ::Tuple{}, ::Tuple{}) = (shp, shp_i)
352-
@inline _rshps(shp, shp_i, ::Tuple{}, ::Tuple{}, o) =
353-
_rshps((shp..., o[1]), (shp_i..., 1), (), (), tail(o))
354-
@inline _rshps(shp, shp_i, ::Tuple{}, i, ::Tuple{}) = (n = i[1];
355-
_rshps((shp..., n), (shp_i..., n), (), tail(i), ()))
356-
@inline _rshps(shp, shp_i, ::Tuple{}, i, o) = (n = i[1];
357-
_rshps((shp..., n * o[1]), (shp_i..., n), (), tail(i), tail(o)))
358-
@inline _rshps(shp, shp_i, sz, i, o) = (n = sz[1] * i[1];
359-
_rshps((shp..., n * o[1]), (shp_i..., n), tail(sz), tail(i), tail(o)))
360-
_rshps(shp, shp_i, sz, ::Tuple{}, ::Tuple{}) =
361-
(n = length(shp); N = n + length(sz); _reperr("inner", n, N))
362-
_rshps(shp, shp_i, sz, ::Tuple{}, o) =
363-
(n = length(shp); N = n + length(sz); _reperr("inner", n, N))
364-
_rshps(shp, shp_i, sz, i, ::Tuple{}) =
365-
(n = length(shp); N = n + length(sz); _reperr("outer", n, N))
366-
_reperr(s, n, N) = throw(ArgumentError("number of " * s * " repetitions " *
367-
"($n) cannot be less than number of dimensions of input ($N)"))
368-
369-
_negreperr(n) = throw(ArgumentError("number of $n repetitions" *
370-
"cannot be negative"))
371-
372-
@noinline function _repeat(A::AbstractArray, inner, outer)
373-
any(<(0), inner) && _negreperr("inner")
374-
any(<(0), outer) && _negreperr("outer")
375-
376-
shape, inner_shape = rep_shapes(A, inner, outer)
377-
378-
R = similar(A, shape)
379-
if any(iszero, shape)
380-
return R
354+
function check(arr, inner, outer)
355+
if inner !== nothing
356+
# TODO: Currently one based indexing is demanded for inner !== nothing,
357+
# but not for outer !== nothing. Decide for something consistent.
358+
Base.require_one_based_indexing(arr)
359+
if any(<(0), inner)
360+
throw(ArgumentError("no inner repetition count may be negative; got $inner"))
361+
end
362+
if length(inner) < ndims(arr)
363+
throw(ArgumentError("number of inner repetitions ($(length(inner))) cannot be less than number of dimensions of input array ($(ndims(arr)))"))
364+
end
365+
end
366+
if outer !== nothing
367+
if any(<(0), outer)
368+
throw(ArgumentError("no outer repetition count may be negative; got $outer"))
369+
end
370+
if (length(outer) < ndims(arr)) && (inner !== nothing)
371+
throw(ArgumentError("number of outer repetitions ($(length(outer))) cannot be less than number of dimensions of input array ($(ndims(arr)))"))
372+
end
381373
end
374+
end
382375

383-
# fill the first inner block
384-
if all(isequal(1), inner)
385-
idxs = (axes(A)..., ntuple(n->OneTo(1), ndims(R)-ndims(A))...) # keep dimension consistent
386-
R[idxs...] = A
387-
else
388-
inner_indices = [1:n for n in inner]
389-
for c in CartesianIndices(axes(A))
390-
for i in 1:ndims(A)
391-
n = inner[i]
392-
inner_indices[i] = (1:n) .+ ((c[i] - 1) * n)
393-
end
394-
fill!(view(R, inner_indices...), A[c])
376+
repeat_inner_outer(arr, inner::Nothing, outer::Nothing) = arr
377+
repeat_inner_outer(arr, ::Nothing, outer) = repeat_outer(arr, outer)
378+
repeat_inner_outer(arr, inner, ::Nothing) = repeat_inner(arr, inner)
379+
repeat_inner_outer(arr, inner, outer) = repeat_outer(repeat_inner(arr, inner), outer)
380+
381+
function repeat_outer(a::AbstractMatrix, (m,n)::NTuple{2, Any})
382+
o, p = size(a,1), size(a,2)
383+
b = similar(a, o*m, p*n)
384+
for j=1:n
385+
d = (j-1)*p+1
386+
R = d:d+p-1
387+
for i=1:m
388+
c = (i-1)*o+1
389+
@inbounds b[c:c+o-1, R] = a
395390
end
396391
end
392+
return b
393+
end
397394

398-
# fill the outer blocks along each dimension
399-
if all(isequal(1), outer)
400-
return R
395+
function repeat_outer(a::AbstractVector, (m,)::Tuple{Any})
396+
o = length(a)
397+
b = similar(a, o*m)
398+
for i=1:m
399+
c = (i-1)*o+1
400+
@inbounds b[c:c+o-1] = a
401401
end
402-
src_indices = [1:n for n in inner_shape]
403-
dest_indices = copy(src_indices)
404-
for i in eachindex(outer)
405-
B = view(R, src_indices...)
406-
for j in 2:outer[i]
407-
dest_indices[i] = dest_indices[i] .+ inner_shape[i]
408-
R[dest_indices...] = B
402+
return b
403+
end
404+
405+
function repeat_outer(arr::AbstractArray{<:Any,N}, dims::NTuple{N,Any}) where {N}
406+
insize = size(arr)
407+
outsize = map(*, insize, dims)
408+
out = similar(arr, outsize)
409+
for I in CartesianIndices(arr)
410+
for J in CartesianIndices(dims)
411+
TIJ = map(Tuple(I), Tuple(J), insize) do i, j, d
412+
i + d * (j-1)
413+
end
414+
IJ = CartesianIndex(TIJ)
415+
@inbounds out[IJ] = arr[I]
409416
end
410-
src_indices[i] = dest_indices[i] = 1:shape[i]
411417
end
418+
return out
419+
end
412420

413-
return R
421+
function repeat_inner(arr, inner)
422+
basedims = size(arr)
423+
outsize = map(*, size(arr), inner)
424+
out = similar(arr, outsize)
425+
for I in CartesianIndices(arr)
426+
for J in CartesianIndices(inner)
427+
TIJ = map(Tuple(I), Tuple(J), inner) do i, j, d
428+
(i-1) * d + j
429+
end
430+
IJ = CartesianIndex(TIJ)
431+
@inbounds out[IJ] = arr[I]
432+
end
433+
end
434+
return out
414435
end
415436

437+
end#module
438+
416439
"""
417440
eachrow(A::AbstractVecOrMat)
418441

base/array.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1352,9 +1352,9 @@ function _deleteat!(a::Vector, inds, dltd=Nowhere())
13521352
n = length(a)
13531353
y = iterate(inds)
13541354
y === nothing && return a
1355-
n == 0 && throw(BoundsError(a, inds))
13561355
(p, s) = y
1357-
p <= n && push!(dltd, @inbounds a[p])
1356+
checkbounds(a, p)
1357+
push!(dltd, @inbounds a[p])
13581358
q = p+1
13591359
while true
13601360
y = iterate(inds, s)

base/cartesian.jl

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -353,17 +353,27 @@ const exprresolve_cond_dict = Dict{Symbol,Function}(:(==) => ==,
353353
:(<) => <, :(>) => >, :(<=) => <=, :(>=) => >=)
354354

355355
function exprresolve_arith(ex::Expr)
356-
if ex.head === :call && haskey(exprresolve_arith_dict, ex.args[1]) && all([isa(ex.args[i], Number) for i = 2:length(ex.args)])
357-
return true, exprresolve_arith_dict[ex.args[1]](ex.args[2:end]...)
356+
if ex.head === :call
357+
callee = ex.args[1]
358+
if isa(callee, Symbol)
359+
if haskey(exprresolve_arith_dict, callee) && all(Bool[isa(ex.args[i], Number) for i = 2:length(ex.args)])
360+
return true, exprresolve_arith_dict[callee](ex.args[2:end]...)
361+
end
362+
end
358363
end
359364
false, 0
360365
end
361366
exprresolve_arith(arg) = false, 0
362367

363368
exprresolve_conditional(b::Bool) = true, b
364369
function exprresolve_conditional(ex::Expr)
365-
if ex.head === :call && ex.args[1] keys(exprresolve_cond_dict) && isa(ex.args[2], Number) && isa(ex.args[3], Number)
366-
return true, exprresolve_cond_dict[ex.args[1]](ex.args[2], ex.args[3])
370+
if ex.head === :call
371+
callee = ex.args[1]
372+
if isa(callee, Symbol)
373+
if callee keys(exprresolve_cond_dict) && isa(ex.args[2], Number) && isa(ex.args[3], Number)
374+
return true, exprresolve_cond_dict[callee](ex.args[2], ex.args[3])
375+
end
376+
end
367377
end
368378
false, false
369379
end

base/compiler/compiler.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ using Core.Intrinsics, Core.IR
77
import Core: print, println, show, write, unsafe_write, stdout, stderr,
88
_apply, _apply_iterate, svec, apply_type, Builtin, IntrinsicFunction, MethodInstance, CodeInstance
99

10-
const getproperty = getfield
11-
const setproperty! = setfield!
10+
const getproperty = Core.getfield
11+
const setproperty! = Core.setfield!
1212

1313
ccall(:jl_set_istopmod, Cvoid, (Any, Bool), Compiler, false)
1414

base/compiler/optimize.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,9 @@ function optimize(opt::OptimizationState, params::OptimizationParams, @nospecial
186186
if length(ir.stmts) < 10
187187
proven_pure = true
188188
for i in 1:length(ir.stmts)
189-
stmt = ir.stmts[i]
190-
if stmt_affects_purity(stmt, ir) && !stmt_effect_free(stmt, ir.types[i], ir, ir.sptypes)
189+
node = ir.stmts[i]
190+
stmt = node[:inst]
191+
if stmt_affects_purity(stmt, ir) && !stmt_effect_free(stmt, node[:type], ir, ir.sptypes)
191192
proven_pure = false
192193
break
193194
end

base/compiler/ssair/driver.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,16 @@ function convert_to_ircode(ci::CodeInfo, code::Vector{Any}, coverage::Bool, narg
116116
end
117117
strip_trailing_junk!(ci, code, flags)
118118
cfg = compute_basic_blocks(code)
119-
ir = IRCode(code, Any[], ci.codelocs, flags, cfg, collect(LineInfoNode, ci.linetable), sv.slottypes, meta, sv.sptypes)
119+
types = Any[]
120+
stmts = InstructionStream(code, types, ci.codelocs, flags)
121+
ir = IRCode(stmts, cfg, collect(LineInfoNode, ci.linetable), sv.slottypes, meta, sv.sptypes)
120122
return ir
121123
end
122124

123125
function slot2reg(ir::IRCode, ci::CodeInfo, nargs::Int, sv::OptimizationState)
124126
# need `ci` for the slot metadata, IR for the code
125127
@timeit "domtree 1" domtree = construct_domtree(ir.cfg)
126-
defuse_insts = scan_slot_def_use(nargs, ci, ir.stmts)
128+
defuse_insts = scan_slot_def_use(nargs, ci, ir.stmts.inst)
127129
@timeit "construct_ssa" ir = construct_ssa!(ci, ir, domtree, defuse_insts, nargs, sv.sptypes, sv.slottypes) # consumes `ir`
128130
return ir
129131
end

0 commit comments

Comments
 (0)