Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add some CFG manipulation tools for IRCode #4

Open
wants to merge 3,932 commits into
base: JuliaFormatter
Choose a base branch
from
Open

Conversation

tkf
Copy link
Owner

@tkf tkf commented May 20, 2022

No description provided.

base/compiler/ssair/ir.jl Show resolved Hide resolved
base/compiler/ssair/ir.jl Show resolved Hide resolved
base/compiler/utilities.jl Show resolved Hide resolved
@tkf tkf force-pushed the JuliaFormatter branch 2 times, most recently from 6f43225 to c466ecb Compare May 23, 2022 08:58
@tkf tkf closed this May 23, 2022
@tkf tkf reopened this May 23, 2022
KristofferC pushed a commit that referenced this pull request Aug 31, 2022
…Lang#45790)

Currently the `@nospecialize`-d `push!(::Vector{Any}, ...)` can only
take a single item and we will end up with runtime dispatch when we try
to call it with multiple items:
```julia
julia> code_typed(push!, (Vector{Any}, Any))
1-element Vector{Any}:
 CodeInfo(
1 ─      $(Expr(:foreigncall, :(:jl_array_grow_end), Nothing, svec(Any, UInt64), 0, :(:ccall), Core.Argument(2), 0x0000000000000001, 0x0000000000000001))::Nothing
│   %2 = Base.arraylen(a)::Int64
│        Base.arrayset(true, a, item, %2)::Vector{Any}
└──      return a
) => Vector{Any}

julia> code_typed(push!, (Vector{Any}, Any, Any))
1-element Vector{Any}:
 CodeInfo(
1 ─ %1 = Base.append!(a, iter)::Vector{Any}
└──      return %1
) => Vector{Any}
```

This commit adds a new specialization that it can take arbitrary-length
items. Our compiler should still be able to optimize the single-input 
case as before via the dispatch mechanism.
```julia
julia> code_typed(push!, (Vector{Any}, Any))
1-element Vector{Any}:
 CodeInfo(
1 ─      $(Expr(:foreigncall, :(:jl_array_grow_end), Nothing, svec(Any, UInt64), 0, :(:ccall), Core.Argument(2), 0x0000000000000001, 0x0000000000000001))::Nothing
│   %2 = Base.arraylen(a)::Int64
│        Base.arrayset(true, a, item, %2)::Vector{Any}
└──      return a
) => Vector{Any}

julia> code_typed(push!, (Vector{Any}, Any, Any))
1-element Vector{Any}:
 CodeInfo(
1 ─ %1  = Base.arraylen(a)::Int64
│         $(Expr(:foreigncall, :(:jl_array_grow_end), Nothing, svec(Any, UInt64), 0, :(:ccall), Core.Argument(2), 0x0000000000000002, 0x0000000000000002))::Nothing
└──       goto JuliaLang#7 if not true
2 ┄ %4  = φ (#1 => 1, JuliaLang#6 => %14)::Int64
│   %5  = φ (#1 => 1, JuliaLang#6 => %15)::Int64
│   %6  = Base.getfield(x, %4, true)::Any
│   %7  = Base.add_int(%1, %4)::Int64
│         Base.arrayset(true, a, %6, %7)::Vector{Any}
│   %9  = (%5 === 2)::Bool
└──       goto #4 if not %9
3 ─       goto JuliaLang#5
4 ─ %12 = Base.add_int(%5, 1)::Int64
└──       goto JuliaLang#5
5 ┄ %14 = φ (#4 => %12)::Int64
│   %15 = φ (#4 => %12)::Int64
│   %16 = φ (#3 => true, #4 => false)::Bool
│   %17 = Base.not_int(%16)::Bool
└──       goto JuliaLang#7 if not %17
6 ─       goto #2
7 ┄       return a
) => Vector{Any}
```

This commit also adds the equivalent implementations for `pushfirst!`.
KristofferC pushed a commit that referenced this pull request Aug 31, 2022
When calling `jl_error()` or `jl_errorf()`, we must check to see if we
are so early in the bringup process that it is dangerous to attempt to
construct a backtrace because the data structures used to provide line
information are not properly setup.

This can be easily triggered by running:

```
julia -C invalid
```

On an `i686-linux-gnu` build, this will hit the "Invalid CPU Name"
branch in `jitlayers.cpp`, which calls `jl_errorf()`.  This in turn
calls `jl_throw()`, which will eventually call `jl_DI_for_fptr` as part
of the backtrace printing process, which fails as the object maps are
not fully initialized.  See the below `gdb` stacktrace for details:

```
$ gdb -batch -ex 'r' -ex 'bt' --args ./julia -C invalid
...
fatal: error thrown and no exception handler available.
ErrorException("Invalid CPU name "invalid".")

Thread 1 "julia" received signal SIGSEGV, Segmentation fault.
0xf75bd665 in std::_Rb_tree<unsigned int, std::pair<unsigned int const, JITDebugInfoRegistry::ObjectInfo>, std::_Select1st<std::pair<unsigned int const, JITDebugInfoRegistry::ObjectInfo> >, std::greater<unsigned int>, std::allocator<std::pair<unsigned int const, JITDebugInfoRegistry::ObjectInfo> > >::lower_bound (__k=<optimized out>, this=0x248) at /usr/local/i686-linux-gnu/include/c++/9.1.0/bits/stl_tree.h:1277
1277    /usr/local/i686-linux-gnu/include/c++/9.1.0/bits/stl_tree.h: No such file or directory.
 #0  0xf75bd665 in std::_Rb_tree<unsigned int, std::pair<unsigned int const, JITDebugInfoRegistry::ObjectInfo>, std::_Select1st<std::pair<unsigned int const, JITDebugInfoRegistry::ObjectInfo> >, std::greater<unsigned int>, std::allocator<std::pair<unsigned int const, JITDebugInfoRegistry::ObjectInfo> > >::lower_bound (__k=<optimized out>, this=0x248) at /usr/local/i686-linux-gnu/include/c++/9.1.0/bits/stl_tree.h:1277
 #1  std::map<unsigned int, JITDebugInfoRegistry::ObjectInfo, std::greater<unsigned int>, std::allocator<std::pair<unsigned int const, JITDebugInfoRegistry::ObjectInfo> > >::lower_bound (__x=<optimized out>, this=0x248) at /usr/local/i686-linux-gnu/include/c++/9.1.0/bits/stl_map.h:1258
 #2  jl_DI_for_fptr (fptr=4155049385, symsize=symsize@entry=0xffffcfa8, slide=slide@entry=0xffffcfa0, Section=Section@entry=0xffffcfb8, context=context@entry=0xffffcf94) at /cache/build/default-amdci5-4/julialang/julia-master/src/debuginfo.cpp:1181
 #3  0xf75c056a in jl_getFunctionInfo_impl (frames_out=0xffffd03c, pointer=4155049385, skipC=0, noInline=0) at /cache/build/default-amdci5-4/julialang/julia-master/src/debuginfo.cpp:1210
 #4  0xf7a6ca98 in jl_print_native_codeloc (ip=4155049385) at /cache/build/default-amdci5-4/julialang/julia-master/src/stackwalk.c:636
 JuliaLang#5  0xf7a6cd54 in jl_print_bt_entry_codeloc (bt_entry=0xf0798018) at /cache/build/default-amdci5-4/julialang/julia-master/src/stackwalk.c:657
 JuliaLang#6  jlbacktrace () at /cache/build/default-amdci5-4/julialang/julia-master/src/stackwalk.c:1090
 JuliaLang#7  0xf7a3cd2b in ijl_no_exc_handler (e=0xf0794010) at /cache/build/default-amdci5-4/julialang/julia-master/src/task.c:605
 JuliaLang#8  0xf7a3d10a in throw_internal (ct=ct@entry=0xf070c010, exception=<optimized out>, exception@entry=0xf0794010) at /cache/build/default-amdci5-4/julialang/julia-master/src/task.c:638
 JuliaLang#9  0xf7a3d330 in ijl_throw (e=0xf0794010) at /cache/build/default-amdci5-4/julialang/julia-master/src/task.c:654
 JuliaLang#10 0xf7a905aa in ijl_errorf (fmt=fmt@entry=0xf7647cd4 "Invalid CPU name \"%s\".") at /cache/build/default-amdci5-4/julialang/julia-master/src/rtutils.c:77
 JuliaLang#11 0xf75a4b22 in (anonymous namespace)::createTargetMachine () at /cache/build/default-amdci5-4/julialang/julia-master/src/jitlayers.cpp:823
 JuliaLang#12 JuliaOJIT::JuliaOJIT (this=<optimized out>) at /cache/build/default-amdci5-4/julialang/julia-master/src/jitlayers.cpp:1044
 JuliaLang#13 0xf7531793 in jl_init_llvm () at /cache/build/default-amdci5-4/julialang/julia-master/src/codegen.cpp:8585
 JuliaLang#14 0xf75318a8 in jl_init_codegen_impl () at /cache/build/default-amdci5-4/julialang/julia-master/src/codegen.cpp:8648
 JuliaLang#15 0xf7a51a52 in jl_restore_system_image_from_stream (f=<optimized out>) at /cache/build/default-amdci5-4/julialang/julia-master/src/staticdata.c:2131
 JuliaLang#16 0xf7a55c03 in ijl_restore_system_image_data (buf=0xe859c1c0 <jl_system_image_data> "8'\031\003", len=125161105) at /cache/build/default-amdci5-4/julialang/julia-master/src/staticdata.c:2184
 JuliaLang#17 0xf7a55cf9 in jl_load_sysimg_so () at /cache/build/default-amdci5-4/julialang/julia-master/src/staticdata.c:424
 JuliaLang#18 ijl_restore_system_image (fname=0x80a0900 "/build/bk_download/julia-d78fdad601/lib/julia/sys.so") at /cache/build/default-amdci5-4/julialang/julia-master/src/staticdata.c:2157
 JuliaLang#19 0xf7a3bdfc in _finish_julia_init (rel=rel@entry=JL_IMAGE_JULIA_HOME, ct=<optimized out>, ptls=<optimized out>) at /cache/build/default-amdci5-4/julialang/julia-master/src/init.c:741
 JuliaLang#20 0xf7a3c8ac in julia_init (rel=<optimized out>) at /cache/build/default-amdci5-4/julialang/julia-master/src/init.c:728
 JuliaLang#21 0xf7a7f61d in jl_repl_entrypoint (argc=<optimized out>, argv=0xffffddf4) at /cache/build/default-amdci5-4/julialang/julia-master/src/jlapi.c:705
 JuliaLang#22 0x080490a7 in main (argc=3, argv=0xffffddf4) at /cache/build/default-amdci5-4/julialang/julia-master/cli/loader_exe.c:59
```

To prevent this, we simply avoid calling `jl_errorf` this early in the
process, punting the problem to a later PR that can update guard
conditions within `jl_error*`.
vtjnash pushed a commit that referenced this pull request Sep 27, 2023
This commit improves SROA pass by extending the `unswitchtupleunion`
optimization to handle the general parametric types, e.g.:
```julia
julia> struct A{T}
           x::T
       end;

julia> function foo(a1, a2, c)
           t = c ? A(a1) : A(a2)
           return getfield(t, :x)
       end;

julia> only(Base.code_ircode(foo, (Int,Float64,Bool); optimize_until="SROA"))
```

> Before
```
2 1 ─      goto #3 if not _4                                          │
  2 ─ %2 = %new(A{Int64}, _2)::A{Int64}                               │╻ A
  └──      goto #4                                                    │
  3 ─ %4 = %new(A{Float64}, _3)::A{Float64}                           │╻ A
  4 ┄ %5 = φ (#2 => %2, #3 => %4)::Union{A{Float64}, A{Int64}}        │
3 │   %6 = Main.getfield(%5, :x)::Union{Float64, Int64}               │
  └──      return %6                                                  │
   => Union{Float64, Int64}
```

> After
```
julia> only(Base.code_ircode(foo, (Int,Float64,Bool); optimize_until="SROA"))
2 1 ─      goto #3 if not _4                                           │
  2 ─      nothing::A{Int64}                                           │╻ A
  └──      goto #4                                                     │
  3 ─      nothing::A{Float64}                                         │╻ A
  4 ┄ %8 = φ (#2 => _2, #3 => _3)::Union{Float64, Int64}               │
  │        nothing::Union{A{Float64}, A{Int64}}
3 │   %6 = %8::Union{Float64, Int64}                                   │
  └──      return %6                                                   │
   => Union{Float64, Int64}
```
aviatesk and others added 21 commits November 9, 2023 10:48
- fixed index of `order` when there are 5 arguments
- add type check for `boundscheck` argument
…aLang#52089)

Stdlib: SparseArrays
URL: https://github.com/JuliaSparse/SparseArrays.jl.git
Stdlib branch: main
Julia branch: master
Old commit: 3582898
New commit: 37fc321
Julia version: 1.11.0-DEV
SparseArrays version: 1.11.0
Bump invoked by: @ViralBShah
Powered by:
[BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl)

Diff:
JuliaSparse/SparseArrays.jl@3582898...37fc321

```
$ git log --oneline 3582898..37fc321
37fc321 test: relax allocated tests (JuliaLang#468)
bd2bda8 replace ind2sub/sub2ind by CartesianIndices/LinearIndices (JuliaLang#451)
7897f1f test: somewhat more permissive test_throws message (JuliaLang#466)
911cf6a `reverse` for sparse vector/matrix (JuliaLang#450)
713a260 Define algebraic operators for SparseMatrixCSCView (JuliaLang#458)
f455a8e Add messages to DimensionMismatch errors (JuliaLang#461)
81fc6f3 Aggressive constprop in sparse * dense (JuliaLang#460)
0b36fdd fix h/vcat invoke dispatch arguments (JuliaLang#464)
6b23902 Add Finch to list of External Julia Sparse Array Libraries (JuliaLang#462)
```

Co-authored-by: Dilum Aluthge <dilum@aluthge.com>
Since now effects can be refined by post-opt analysis, `typeinf_edge`
should propagate `frame.result.ipo_effects` instead of
`frame.ipo_effects`.
…uliaLang#52085)

Since now effects can be refined by post-opt analysis, `typeinf_edge`
should propagate `frame.result.ipo_effects` instead of
`frame.ipo_effects`.
…iaLang#52064)

It feels a bit inconsistent that the `src` argument of `inlining_policy`
needs to handle `SemiConcreteResult` while it doesn't need to handle the
other container objects that propagates sources like `CodeInstance`
`InferenceResult`, or `VolatileInferenceResult`.

This commit makes `inlining_policy` take `result.ir::IRCode` instead
when dealing with `result::SemiConcreteResult` for more consistency and
clarity.
Two chagnes wrapped into one `Base.copymutable` => `Base.copymutable` &
`collect` and `Base.copymutable` => `similar` & words.

Followup for JuliaLang#52086 and JuliaLang#46104; also fixes JuliaLang#51932 (though we still may
want to make `copymutable` public at some point)

---------

Co-authored-by: Jameson Nash <vtjnash@gmail.com>
Minor optimization to compute index in `Dict` only once.

This PR should not be merged before JuliaLang#52017.

**Master**
``` julia
  126.417 μs (1 allocation: 16 bytes)
  147.812 μs (1 allocation: 16 bytes)
```

**PR**
``` julia
  86.494 μs (1 allocation: 16 bytes)
  156.912 μs (1 allocation: 16 bytes)
```

<details>
<summary><b><u>Testing code</u></b></summary>

``` julia
using BenchmarkTools

function PR_pop!(s::Set, x, default)
    dict = s.dict
    index = Base.ht_keyindex(dict, x)
    if index > 0
        @inbounds key = dict.keys[index]
        Base._delete!(dict, index)
        return key
    else
        return default
    end
end

N = 10000
x = collect(1:N)
x_negative = collect(-N:-1)

function pop_all(s, x)
    for v in x
        pop!(s, v, -1)
    end
end

function pop_all_PR(s, x)
    for v in x
        PR_pop!(s, v, -1)
    end
end

# Master
@Btime pop_all(s, x) setup=(s=Set(x))
@Btime pop_all(s, x_negative) setup=(s=Set(x))

# PR
@Btime pop_all_PR(s, x) setup=(s=Set(x))
@Btime pop_all_PR(s, x_negative) setup=(s=Set(x))
```
</details>
…ng#52088)

A (very) small memory optimization to avoid saving objects that are
essentially unreachable
…the side-effect of calling diff_names for kwarg error checking (JuliaLang#52081)

empirically this makes a very minor difference, but it seems to be at
least very slightly more optimal in bytes allocated for some tests,
though I didn't check very many tests to compare broadly
```
show         (6) |    15.72 |   0.18 |  1.1 |    2695.53 |   696.03
show         (6) |    15.82 |   0.18 |  1.2 |    2734.35 |   707.94
```
…51903)

First we add an optional API parameter for `sizehint!` that controls
whether it is for `push!` (default) or `pushfirst!`. Secondly, we make
the offset zero when using `sizehint!` to shrink an array from the end,
or the trailing size zero when using it to shring from the beginning.

Then we replace the prior implementations of `prepend!` and `append!`
with ones that are safe even if the iterator changes length during the
operation or if convert fails. The result of `prepend!` may be in an
undefined order (because of the `reverse!` call) in the presence of
concurrent modifications or errors, but at least all of the elements
will be present and valid afterwards.

Replaces and closes JuliaLang#49905
Replaces and closes JuliaLang#47391
Fixes JuliaLang#15868

Benchmarks show that repeated `push!` performance (with sizehint) is
nearly equivalent to the old append performance:
```
julia> @benchmark append!(x, 1:1000) setup=x=Vector{Float64}(undef,0)
BenchmarkTools.Trial: 10000 samples with 10 evaluations.
 Range (min … max):  1.027 μs … 72.871 μs  ┊ GC (min … max): 0.00% … 94.57%
 Time  (median):     1.465 μs              ┊ GC (median):    0.00%
 Time  (mean ± σ):   1.663 μs ±  1.832 μs  ┊ GC (mean ± σ):  6.20% ±  5.67%

             ▂▃▅▆█▇▇▆▄▂▁                                      
  ▂▁▁▂▂▂▂▃▄▅▇█████████████▇▆▅▅▅▅▅▅▄▅▄▅▅▅▆▇███▆▅▄▃▃▂▂▂▂▂▂▂▂▂▂ ▄
  1.03 μs        Histogram: frequency by time        2.31 μs <

 Memory estimate: 19.69 KiB, allocs estimate: 0.

julia> @benchmark append!(x, 1:1000) setup=x=Vector{Int}(undef,0)
BenchmarkTools.Trial: 10000 samples with 10 evaluations.
 Range (min … max):  851.900 ns … 76.757 μs  ┊ GC (min … max): 0.00% … 91.59%
 Time  (median):       1.181 μs              ┊ GC (median):    0.00%
 Time  (mean ± σ):     1.543 μs ±  1.972 μs  ┊ GC (mean ± σ):  6.75% ±  5.75%

     ▆█▇▃                                                       
  ▂▃██████▇▅▅▄▅▅▃▂▂▂▃▃▃▂▃▃▃▂▂▂▂▂▁▂▁▂▁▂▂▂▁▁▂▂▁▁▁▁▁▁▁▂▂▂▃▃▃▃▂▂▂▂ ▃
  852 ns          Histogram: frequency by time         4.07 μs <

 Memory estimate: 19.69 KiB, allocs estimate: 0.
```

Co-authored-by: Sukera <Seelengrab@users.noreply.github.com>
Co-authored-by: MasonProtter <mason.protter@icloud.com>
)

Tests whether key is updated even if they are equal.

Refs JuliaLang#52066
Currently [1] it is illegal [2] in IRCode to have a GlobalRef in value
position that could potentially throw. This is because in IRCode, we
want to assign flags to every statement and if there are multiple things
with effects in a statement, we lose precision in tracking which they
apply to. However, we currently do allow this in `CodeInfo`. Now that
we're starting to make more use of flags in inference also, this is
becoming annoying (as it did for IRCode), so I would like to do this
transformation earlier. This is an attempt to do this during lowering.
It is not entirely clear that this is precisely the correct place for
it. We could alternatively consider doing it during the global resolve
pass in method.c, but that currently does not renumber SSAValues, so
doing it during the renumbering inside lowering may be easier.

N.B.: This is against JuliaLang#51853, because this needs some of the inference
precision improvements in that PR to avoid regressing the try/catch
elision tests (which before that PR, we were incorrectly computing
effects for statement-position GlobalRefs).

[1]
JuliaLang@39c278b
[2]
https://github.com/JuliaLang/julia/blob/2f63cc99fb134fb4adb7f11ba86a4e2ab5adcd48/base/compiler/ssair/verify.jl#L54-L58

---------

Co-authored-by: Jeff Bezanson <jeff.bezanson@gmail.com>
Co-authored-by: Oscar Smith <oscardssmith@gmail.com>
This code was using the sentinel value -1 as a special marker in
addition to the negative BB indices. That ambiguity was causing
`cfg_simplify!` to fail on functions that merge any BB into the first
basic block.

This change is to use `typemin(Int)` as a marker instead.

Fixes JuliaLang#52058
stevengj and others added 30 commits December 13, 2023 10:05
This reverts commit 4801b6c and adds
the safepoints needed to catch the unsafe->safe transition also and the
locks needed for the condition broadcast message to be seen.
Could be observed by thread 0 during certain phases, since if the dying
thread was not running, it was not supposed to call jl_wakeup_thread
(which will not increment nrunning until after the wakeup).
This gets some functions working with immutable matrix types, e.g.:
```julia
julia> using FillArrays, LinearAlgebra

julia> F = Fill(big(2), 4, 4)
4×4 Fill{BigInt}, with entries equal to 2

julia> det(F)
0

julia> triu(F)
4×4 Matrix{BigInt}:
 2  2  2  2
 0  2  2  2
 0  0  2  2
 0  0  0  2
```
We still don't model exceptions, but the :leave expression doesn't
participate in type refinement, so adding it here is easy.
…ng#46604)

Our type intersection "prefers" `Tuple` with more parameters.
This PR tries to replace `Tuple{Vararg{T,N}}` with
`Tuple{T,T,T,Vararg{T,N}}` during re-intersection if we can prove that
`N >= 3` and `N` is used only for Vararg length.
This PR forwards `AbstractUnitRange` indices for `FastSubArrays` to the
parent, making use of the fact that the parent might have efficient
vector indexing methods defined.

---------

Co-authored-by: Jishnu Bhattacharya <jishnub@users.noreply.github.com>
Co-authored-by: N5N3 <2642243996@qq.com>
Co-authored-by: Dilum Aluthge <dilum@aluthge.com>
…u -> \Mu) (JuliaLang#50925)

Closes JuliaLang#50911.  Closes JuliaLang#50913.

There were a few oddball symbols prefixed with `\up` (for "upright") for
no reason that I can tell, ala the LaTeX "upgreek" package, even though
we don't use an `\up` prefix for other upright Greek letters (e.g. we
have `\alpha`, not `\upalpha`, even though it isn't italicized — we have
`\italpha` for italic alpha).

Not breaking since this is just a UI thing.

(In practice, I doubt many people use these symbols. e.g. `\upMu` is
`Μ`, which looks a lot like the Latin `M`. But there is no reason to
have the `\up` prefix here. It seems to have just been an automated
abbreviation-import snafu. And [`\upkoppa 'ϟ'`
(U+O3DF)](https://www.compart.com/en/unicode/U+03DF) is visually quite
distinctive though I've never seen it used in math, not to mention
lowercase — it's definitely goofy to have an `\up` prefix for it.)
As commented [on
discourse](https://discourse.julialang.org/t/how-do-we-julians-win-big-when-the-situation-is-so-unfair/106433/63?u=stevengj),
it would be nice if the `permutedims` examples began with something like
an array of strings where `transpose` is inapplicable.

This PR simply clarifies the docs and adds a few more examples.

---------

Co-authored-by: Haakon Ludvig Langeland Ervik <45243236+haakon-e@users.noreply.github.com>
Co-authored-by: Jishnu Bhattacharya <jishnub.github@gmail.com>
…liaLang#52362)

This is based on

```julia
julia> using Pkg

help?> Pkg.add
...
  │ Note
  │
  │  To change the default strategy to PRESERVE_TIERED_INSTALLED set the env var
  │  JULIA_PKG_PRESERVE_TIERED_INSTALLED to true.
...
```

I suggest to backport this so that it becomes available in the release
docs of Julia v1.9 and newer.
)

This replaces JuliaLang#50909, though
notably does not include the change to use heap size instead of heap
memory.

This adds the smoothing behavior from that prior PR (to better estimate
the long-term rates / ignore transient changes), updates the GC_TIME
printing to reflect the change to use MemBalancer heuristics, and adds
some other guardrails to the decisions so they do not get put off too
far into the future. Since, unlike several other languages that use
MemBalancer, we do not have a time-based trigger for GC to update these
heuristics continuously, so we need to make sure each step is reasonably
conservative (both from under and over predicting the rate). Finally,
this is stricter about observing limits set by the user, by strictly
limiting the exceedence rate to around 10%, while avoiding some prior
possible issues with the hard cut-off being disjoint at the cutoff. This
should mean we will go over the threshold slowly if the program
continues to demand more space. If we OOM eventually by the kerenl, we
would have died anyways from OOM now by ourself.
…ng#52548)

What observed in JuliaLang#52531 is that `QuoteNode` can embed global variables
that users can modify. Therefore, when dealing with `QuoteNode`, it's
necessary to taint its `:inaccessiblememonly` just like we do for
`GlobalRef`.

- fixes JuliaLang#52531
- replaces JuliaLang#52536
…ex (JuliaLang#52512)

Annotate several `getindex`/`setindex!` methods with
`@propagate_inbounds`. We may need to be a bit careful to check for
errant `@inbounds` annotations without a corresponding bounds-check.

Close JuliaLang#52550
)

Partly revert and redesign JuliaLang#52115, with `diagind` now accepting an
optional `IndexStyle`, which is `IndexLinear` by default. This should
address the breakages reported in that PR. After this,
```julia
julia> D = Diagonal(1:4)
4×4 Diagonal{Int64, UnitRange{Int64}}:
 1  ⋅  ⋅  ⋅
 ⋅  2  ⋅  ⋅
 ⋅  ⋅  3  ⋅
 ⋅  ⋅  ⋅  4

julia> diagind(D)
1:5:16

julia> diagind(D, IndexCartesian())
StepRangeLen(CartesianIndex(1, 1), CartesianIndex(1, 1), 4)
```

---------

Co-authored-by: Daniel Karrasch <daniel.karrasch@posteo.de>
On master
```julia
julia> copy(Diagonal(1:4)) |> typeof
Diagonal{Int64, Vector{Int64}}
```
This PR
```julia
julia> copy(Diagonal(1:4)) |> typeof
Diagonal{Int64, UnitRange{Int64}}
```
Similar methods already exist for `Bidiagonal` and `Tridiagonal`, but
this was missing for `Diagonal`.
The impact of this typo was a) massively decreased performance that was
b) predicted by heuristic dispatch, resulting in this algorithm not
being dispatched too. I introduced this typo in
187e8c2 after performing all the benchmarking and before merging.
Should fix JuliaLang#52558. `a` should be rooted before the alloc call. I removed
the comment as it seemed to refer to a write barrier that was removed
long ago.
Fixes
```julia
julia> using FillArrays, LinearAlgebra

julia> U = UnitUpperTriangular(Fill(2,4,4))
4×4 UnitUpperTriangular{Int64, Fill{Int64, 2, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}}}:
 1  2  2  2
 ⋅  1  2  2
 ⋅  ⋅  1  2
 ⋅  ⋅  ⋅  1

julia> -U
ERROR: ArgumentError: Cannot setindex! to -1 for an AbstractFill with value -2.
Stacktrace:
 [1] setindex!
   @ ~/.julia/packages/FillArrays/oXkMk/src/FillArrays.jl:52 [inlined]
 [2] -(A::UnitUpperTriangular{Int64, Fill{Int64, 2, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}}})
   @ LinearAlgebra ~/packages/julias/julia-latest/share/julia/stdlib/v1.11/LinearAlgebra/src/triangular.jl:442
 [3] top-level scope
   @ REPL[33]:1
```
After this,
```julia
julia> -U
4×4 UpperTriangular{Int64, Matrix{Int64}}:
 -1  -2  -2  -2
  ⋅  -1  -2  -2
  ⋅   ⋅  -1  -2
  ⋅   ⋅   ⋅  -1
```
…ng#52527)

Currently, our try/catch elision code does not look at whether the
EnterNode has a scope, and just deletes it, if it can prove the contents
nothrow. This is obviously problematic, so this fixes that case up to
instead set the catch dest to 0 in that case (along with support in the
rest of the system to ignore such catch dests for the purpose of
renaming). The idea is that a later pass could use the notasklocalstate
effect to delete this after appropriate verification, but this is not
implemented. Additionally, this currently bails on folding current_scope
inside such try/catch regions - for such regions we cannot use the CFG
to determine the extent of the try/catch region. A proper treatment of
this would probably be to just treat this as a single value mutable -
but again this is not implemented. The primary purpose of this patch is
to ensure correctness.
This redoes JuliaLang#52369, to put the walk through tothe chained KeyValue into
a more logical place (the definition walking). This way, we
automatically inherit correct handling of PhiNodes and ifelse.
Equivalent of JuliaLang#50586; implements
JuliaLang#51474.

With `--pkgimages=existing`, it's possible to disable the (often slow)
generation of package images, without losing the ability to use existing
ones. That's important now that we're moving more and more packages
outside of the system image, e.g., running with `--pkgimages=no`
otherwise takes close to 30s here before the Pkg REPL is usable.

The main motivation for this is PkgEval, where generating package images
is not very useful, yet disabling generation of them makes each job
(which requires Pkg to drive the test process) take a significantly
longer time.

For example, `--pkgimages=yes` vs `no`:

```julia
❯ JULIA_DEBUG=loading ./julia --project=Example.jl --pkgimages=yes
# no precompilation of REPL.jl
┌ Debug: Loading object cache file /Users/tim/Julia/src/julia/build/dev/usr/share/julia/compiled/v1.11/REPL/u0gqU_XmENM.dylib for REPL [3fa0cd96-eef1-5676-8a61-b3b8758bbffb]
└ @ Base loading.jl:1116

julia> using Example
# short time precompiling + pkgimg generation for Example.jl
┌ Debug: Loading object cache file /Users/tim/.julia/compiled/v1.11/Example/lLvWP_tJaso.dylib for Example [7876af07-990d-54b4-ab0e-23690620f79a]
└ @ Base loading.jl:1116
```

```julia
❯ JULIA_DEBUG=loading ./julia --project=Example.jl --pkgimages=no
┌ Debug: Rejecting cache file /Users/tim/Julia/src/julia/build/dev/usr/share/julia/compiled/v1.11/REPL/u0gqU_XmENM.ji for REPL [3fa0cd96-eef1-5676-8a61-b3b8758bbffb] since the flags are mismatched
│   current session: use_pkgimages = false, debug_level = 1, check_bounds = 0, inline = true, opt_level = 2
│   cache file:      use_pkgimages = true, debug_level = 1, check_bounds = 0, inline = true, opt_level = 2
└ @ Base loading.jl:3289
# long time precompiling REPL.jl
┌ Debug: Loading cache file /Users/tim/.julia/compiled/v1.11/REPL/u0gqU_CWvWI.ji for REPL [3fa0cd96-eef1-5676-8a61-b3b8758bbffb]
└ @ Base loading.jl:1119

julia> using Example
# short time precompiling Example
┌ Debug: Loading cache file /Users/tim/.julia/compiled/v1.11/Example/lLvWP_CWvWI.ji for Example [7876af07-990d-54b4-ab0e-23690620f79a]
└ @ Base loading.jl:1119
```

With the new `--pkgimages=existing`:

```julia
❯ JULIA_DEBUG=loading ./julia --project=Example.jl --pkgimages=existing
# no precompilation of REPL.jl
┌ Debug: Loading object cache file /Users/tim/Julia/src/julia/build/dev/usr/share/julia/compiled/v1.11/REPL/u0gqU_XmENM.dylib for REPL [3fa0cd96-eef1-5676-8a61-b3b8758bbffb]
└ @ Base loading.jl:1116

julia> using Example
# short time precompiling Example
┌ Debug: Loading cache file /Users/tim/.julia/compiled/v1.11/Example/lLvWP_CWvWI.ji for Example [7876af07-990d-54b4-ab0e-23690620f79a]
└ @ Base loading.jl:1119
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.