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

Backport: Add a new macro @outline, and use it in @assert. #206

Closed
wants to merge 3,511 commits into from

Conversation

NHDaly
Copy link
Member

@NHDaly NHDaly commented Jan 21, 2025

PR Description

Backport JuliaLang#57122.

Checklist

Requirements for merging:

Keno and others added 30 commits November 18, 2024 15:34
This was added in #12568 to protect against a segfault after
`close(stdin)`. However, the API is not great, because the stdin closing
is an asynchronous event, so there isn't really any way to use this API
without inccurring an error. Further, it already returns an error code
of whether or not the action suceeded, and it's bad practice to have two
ways for an operation to fail. Remove the error check and handle a
closed stream gracefully returning an EOF error. In all users in Base,
this EOF error is ignored, but we will gracefully check for EOF later
and shut down the REPL, which is the desired behavior.

Fixes timholy/Revise.jl#859
This eliminates the need to associate a `catch` with every `with(...) do
... end` block, which was really just acting as a landing pad to restore
`jl_current_task->scope` in the majority of cases.

This change does not actually update lowering to remove the unnecessary
`catch` block - that's left as a follow-up.
…5871)

We were accidentally emitting a different pop order for `Expr(:leave,
...)` if you uncomment the `nothing` below:
```julia
let src = Meta.@lower let
    try
        try
            return 1
        catch
        end
    finally
        # nothing # <- uncomment me
    end
end
    println.(filter(stmt->Base.isexpr(stmt, :leave), src.args[1].code))
    nothing
end
```
…g. `--trim`) (#56045)

The intention here is to clearly signal when a feature is "not yet fully
implemented" vs. "feature-complete and in pre-release" vs. "fully
released and ready for production use"

The only feature gated behind this right now is `--trim`. Trim has its
core functionality implemented (and folks seem to be enjoying it!) but
the deployment / linking story in particular is still in its very early
stages, esp. because our existing techniques for, e.g., pre-loading
`libunwind`, `libstdc++`, etc. no longer work in a shared library
context.

Once `--trim` is ready for a broader chunk of the ecosystem / language,
we can peel off the `--experimental` flag
Combines many allocations into one and types them for better inference
…itted (#56612)

This fixes a bug introduced by #55907, which was neglecting that it's
possible for `EnterNode` to have no `catch` destination and still have a
scope.

This can especially happen if the compiler has decided that the body is
`nothrow` and chooses to optimize away the `catch` destination, but also
#55907 intended to make the scope-only form of `:enter` legal (and not
need an exception handler) even if the body is _not_ `nothrow`.

This fixes all that up to restore the scope correctly on the happy path.

~~Needs tests - will add those soon~~
Stdlib: SparseArrays
URL: https://github.com/JuliaSparse/SparseArrays.jl.git
Stdlib branch: main
Julia branch: master
Old commit: 14333ea
New commit: 1b4933c
Julia version: 1.12.0-DEV
SparseArrays version: 1.12.0
Bump invoked by: @Keno
Powered by:
[BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl)

Diff:
JuliaSparse/SparseArrays.jl@14333ea...1b4933c

```
$ git log --oneline 14333ea..1b4933c
1b4933c Make `allowscalar` a macro with auto-world-age-increment (#583)
```

Co-authored-by: Dilum Aluthge <[email protected]>
I want to move out LinearAlgebra into its own repository but I still
want to be able to run its tests in parallel. The easiest would be to be
able to use `Base.runtests` but right now it hard codes the path to the
stdlib folder. Instead, use the loading mechanism to look up where the
stdlib of the active project actively resides.
#56409 broke PackageCompiler (or
other use cases where you want to compile a new core compiler from a
release build) since it hardcoded the relative path `../usr/` from Base
to the `shared` directory but this is not true in releases where it is
at `..`.
- incorrect edge types were being added from inlining: there is minimal
dispatch info available, so best not to add that (which was already
added earlier) as it results in failures to validate later
- MethodTable/sig order in edges could confuse the iterator: always put
the type before the edge now as that is more consistent
- edges wasn't converted to a SimpleVector, so they might get ignored
later from being in the wrong format
- edges were not populated for optimize=false, which made debugging them
more inconvenient

Fixes #56577
Previously our precompilation code was causing anything with package A
as a dependency to wait on all of A's extensions and weakdeps to finish
before starting to pre-compile, even if it can't actually load those
weakdeps (or the extensions themselves)

This would lead to a pre-compile ordering like:
```
A        B
 \      / \
  Ext AB   \
     |     /
     C    /
      \  /
       D
```

Here `C` cannot pre-compile in parallel with `Ext {A,B}` and `B`,
because it has to wait for `Ext {A,B}` to finish pre-compiling. That
happens even though `C` has no way to load either of these.

This change updates the pre-compile ordering to be more parallel,
reflecting the true place where `Ext {A,B}` can be loaded:
```
  A       B
 / \     / \
C   Ext AB  |
 \    |    /
  \-- D --/
```

which allows `C` to compile in parallel with `B` and `Ext{A,B}`
This PR introduces a new, toplevel-only, syntax form `:worldinc` that
semantically represents the effect of raising the current task's world
age to the latest world for the remainder of the current toplevel
evaluation (that context being an entry to `eval` or a module
expression). For detailed motivation on why this is desirable, see
#55145, which I won't repeat here, but the gist is that we never really
defined when world-age increments and worse are inconsistent about it.
This is something we need to figure out now, because the bindings
partition work will make world age even more observable via bindings.

Having created a mechanism for world age increments, the big question is
one of policy, i.e. when should these world age increments be inserted.

Several reasonable options exist:
1. After world-age affecting syntax constructs (as proprosed in #55145)
2. Option 1 + some reasonable additional cases that people rely on
3. Before any top level `call` expression
4. Before any expression at toplevel whatsover

As an example, case, consider `a == a` at toplevel. Depending on the
semantics that could either be the same as in local scope, or each of
the four world age dependent lookups (three binding lookups, one method
lookup) could (potentially) occur in a different world age.

The general tradeoff here is between the risk of exposing the user to
confusing world age errors and our ability to optimize top-level code
(in general, any `:worldinc` statement will require us to fully
pessimize or recompile all following code).

This PR basically implements option 2 with the following semantics:

1. The interpreter explicit raises the world age only at `:worldinc`
exprs or after `:module` exprs.
2. The frontend inserts `:worldinc` after all struct definitions, method
definitions, `using` and `import.
3. The `@eval` macro inserts a worldinc following the call to `eval` if
at toplevel
4. A literal (syntactic) call to `include` gains an implicit `worldinc`.

Of these the fourth is probably the most questionable, but is necessary
to make this non-breaking for most code patterns. Perhaps it would have
been better to make `include` a macro from the beginning (esp because it
already has semantics that look a little like reaching into the calling
module), but that ship has sailed.

Unfortunately, I don't see any good intermediate options between this PR
and option #3 above. I think option #3 is closest to what we have right
now, but if we were to choose it and actually fix the soundness issues,
I expect that we would be destroying all performance of global-scope
code. For this reason, I would like to try to make the version in this
PR work, even if the semantics are a little ugly.

The biggest pattern that this PR does not catch is:
```
eval(:(f() = 1))
f()
```

We could apply the same `include` special case to eval, but given the
existence of `@eval` which allows addressing this at the macro level, I
decided not to. We can decide which way we want to go on this based on
what the package ecosystem looks like.
This does two things:

1. Forward `copytrito!` for triangular matrices to the parent in case
the specified `uplo` corresponds to the stored part. This works because
these matrices share their elements with the parents for the stored
part.
2. Make `copytrito!` only copy the diagonal if the `uplo` corresponds to
the non-stored part.

This makes `copytrito!` involving a triangular matrix equivalent to that
involving its parent if the filled part is copied, and O(N) otherwise.

Examples of improvements in performance:
```julia
julia> using LinearAlgebra

julia> A1 = UpperTriangular(rand(400,400));

julia> A2 = similar(A1);

julia> @Btime copytrito!($A2, $A1, 'U');
  70.753 μs (0 allocations: 0 bytes) # nightly v"1.12.0-DEV.1657"
  26.143 μs (0 allocations: 0 bytes) # this PR

julia> @Btime copytrito!(parent($A2), $A1, 'U');
  56.025 μs (0 allocations: 0 bytes) # nightly
  26.633 μs (0 allocations: 0 bytes) # this PR
```
Since `Base.@show` is much useful than `Base.Compiler.@show`.
Stdlib: Pkg
URL: https://github.com/JuliaLang/Pkg.jl.git
Stdlib branch: master
Julia branch: master
Old commit: 9f8e11a4c
New commit: 7b759d7f0
Julia version: 1.12.0-DEV
Pkg version: 1.12.0
Bump invoked by: @IanButterworth
Powered by:
[BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl)

Diff:
JuliaLang/Pkg.jl@9f8e11a...7b759d7

```
$ git log --oneline 9f8e11a4c..7b759d7f0
7b759d7f0 Automatically upgrade empty manifest files to v2 format (#4091)
69c6de019 Remove duplicated word "different" (#4088)
87a4a9172 Actually switch to "Resolving Deltas" (#4080)
ef844e32f Update CHANGELOG.md: link to [sources] PR (#4084)
e10883ce5 REPLExt: check for compliant repl mode during repl init (#4067)
```

Co-authored-by: Dilum Aluthge <[email protected]>
This changes our IR representation to use a CodeInstance directly as
the invoke function target to specify the ABI in its entirety, instead
of just the MethodInstance (specifically for the rettype). That allows
removing the lookup call at that point to decide upon the ABI. It is
based around the idea that eventually we now keep track of these
anyways to form a graph of the inferred edge data, for use later in
validation anyways (instead of attempting to invert the backedges graph
in staticdata_utils.c), so we might as well use the same target type
for the :invoke call representation also now.
The return value of the LLVM instruction `fptosi`
(https://llvm.org/docs/LangRef.html#fptosi-to-instruction) does not
guarantee that the truncation of `NaN` is 0, so we relax the test to
only check that the output has the expected type.

Fix #56582.
Makes `test Compiler` work properly (as in use the Compiler package, not
Base.Compiler) and pass tests, but still needs to be made parallel in a
follow-on.

---------

Co-authored-by: Shuhei Kadowaki <[email protected]>
Co-authored-by: Kristoffer Carlsson <[email protected]>
Co-authored-by: Shuhei Kadowaki <[email protected]>
These builtins are now special-cased within `abstract_call_known` after
#56299, making them unnecessary for basic inference. As a
result, their tfuncs have been removed in the PR. However the algorithm
for calculating inlining costs still looks up these tfuncs, so they need
to be recovered. Additionally, the `generate_builtins.jl` script in
JuliaInterpreter also uses these tfuncs, so it would be worthwhile to
register even simple placeholder tfuncs for now.

@nanosoldier `runbenchmarks("inference", vs=":master")`
This is an alternative to #56532 and can resolve #31909.
Currently `apply_type_tfunc` is unable to handle `Union`-argtypes with
any precision. With this change, `apply_type_tfunc` now performs
union-splitting on `Union`-argtypes and returns the merged result of the
splits.
While this can improve inference precision, we might need to be cautious
about potential inference time bloat.

---------

Co-authored-by: Jameson Nash <[email protected]>
With #56632, Compiler.jl as the stdlib can now be tested.
However, the PR was incomplete, and when tests are actually run on
`Compiler`, which is `!== Base.Compiler`, various errors occur,
including issues caused by #56647.

This commit resolves all these issues:
- manage the code for loading `Compiler` in `setup_Compiler.jl`,
ensuring that the stdlib version of `Compiler` is loaded when `@activate
Compiler` is used beforehand
- replace `Base.IRShow` with `Compiler.IRShow`
- test `Base.Compiler.return_type` instead of `Compiler.return_type`

This was split off from #56636.
…st (#56586)

Moved some `let...end` blocks into `@testset begin ... end` format.
Added a test for converting a string to `Array{UInt8}`. Restored a
commented out testset.
dkarrasch and others added 24 commits January 12, 2025 18:03
[OpenBLAS v0.3.29](https://github.com/OpenMathLib/OpenBLAS/releases) was released just 6 hours ago.

Note that OpenBLAS 0.3.29 [doesn't support building for PowerPC with GCC before v11](OpenMathLib/OpenBLAS#5068 (comment)), which means we can't support libgfortran3 and 4 anymore.
Stdlib: SparseArrays
URL: https://github.com/JuliaSparse/SparseArrays.jl.git
Stdlib branch: main
Julia branch: master
Old commit: 4fd3aad
New commit: 5f52721
Julia version: 1.12.0-DEV
SparseArrays version: 1.12.0
Bump invoked by: @ViralBShah
Powered by:
[BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl)

Diff:
JuliaSparse/SparseArrays.jl@4fd3aad...5f52721

```
$ git log --oneline 4fd3aad..5f52721
5f52721 Update wrappers for SuiteSparse 7.8.3 (#593)
c575811 Mention vectors in more docstrings (#591)
```

Co-authored-by: ViralBShah <[email protected]>
First attempt to address #39713

Original:
```
const a, b, c, d = zeros(Int, 2, 2), [3 4], [2 ; 4], 5
using BenchmarkTools
@Btime [a c ; b d]   # 31 allocations and 1.25 kb
```

New:
```
@Btime [a c ; b d]   # 15 allocations and 656 bytes
```

Others unchanged, as expected. ~~Though if different types of numbers
are mixed, it still takes the longer path. I tried expanding the
definition but there's some weird stuff going on that increases
allocations in the other situations I posted in that issue.~~ Works for
any Number element type.

Fixes #39713
…57033)

By unwrapping the input type in `datatype_min_ninitialized`, and guard
against non `DataType` input by returning the most conservative value
`0` in such cases.

Fixes #56997
…6371)

This used to not work but LLVM now has support for this on all platforms
we care about.

Maybe this should be a builtin.
This allows for more vectorization opportunities since llvm understands
the code better

Fix #48487.

---------

Co-authored-by: Mosè Giordano <[email protected]>
Co-authored-by: oscarddssmith <[email protected]>
Cthulhu.jl requires this (as the signature of `jl_update_codeinst` has
been updated).
This PR fixes #57002. The
current makefile checks if `MMTK_JULIA_DIR` points to
`$(BUILDROOT)/usr/lib/mmtk_julia` and defines the rule `get-mmtk_julia`
if the condition is met. For non-mmtk builds (e.g. `make -C deps
getall`), `MMTK_JULIA_DIR` is not defined, thus `get-mmtk_julia` is not
defined. This PR moves the rule `get-mmtk_julia` outside the condition
so it always exists.
This reverts commit 2bd4cf8. (#53231)

The reason for this revert is that it caused exponential blowup of types
in iterated views causing some packages to simply freeze when doing
something that worked ok in 1.10.

In my opinion, the perf gain from the PR is not outweighed by the "risk"
of hitting this compilation blowup case.

Fixes #56760.

Co-authored-by: KristofferC <[email protected]>
Also add some extra annotations that seemed to be required locally,
though unrelated to the primary change.

Observed on CI:
https://buildkite.com/julialang/julia-master/builds/43693#01946057-7150-4741-a756-79e7d59a7717
Fixes #57042
…57035)

Extend the fix for #43578 on Darwin to also cover the same bug in Glibc
(and just assume other libc have the same bug). We cannot use the same
atfork trick, since the atfork implementation of this in Glibc makes
this unsafe to use this after fork, just like Darwin (though for
different basic concurrency mistakes in each of their respective codes).

Fix #57017
- `PCRE._mth()` now uses `Base._maxthreadid` instead of manual inlining
of `Threads.maxthreadid()`
- `PCRE_COMPILE_LOCK` is now typed global
With #56447, the dependency between `jl_insert_backedges`
and method insertion has been eliminated, allowing `jl_insert_backedges`
to be performed after loading. As a result, it is now possible to move
`jl_insert_backedges` to the Julia side.

Currently this commit simply moves the implementation without adding any
new features.

---------

Co-authored-by: Jameson Nash <[email protected]>
After recent changes, essentially all global symbol scopes are resolved
by lowering, so the code in method.c that replaces symbols by globalrefs
is no longer necessary. The one small exception to this were symbols
resulting from closure conversion, because these get inserted after the
point at which lowering converts symbols to globalrefs. However, in the
current design, I think that's basically a bug (and easily addressed by
inserting `globalref`s where appropriate). Removing this extra
resolution step is not particularly necessary, but for the upcoming
binding partition backedges, it removes an ambiguity as to which version
of the lowered code to scan. It also partially resolves a very old todo
about not performing post-hoc mutation of lowered code (although we
still do this for ccall).
The `@inferred` macro is applied to the following functions:
* `Base.IteratorSize`
* `Base.IteratorEltype`
* `eltype`
* `axes`
* `size`
* `length`
* `ndims`
* `isempty`

xref #56802

xref #56838
#55454 produces the correct URIs
when run on WSL, but the tests don't use the same logic and so they fail
on WSL at the moment. This fixes the tests on WSL.

CC @tecosaur
Macro usage:
```julia
  @BoundsCheck i > 1 && i <= len || @outline throw(BoundsError(x, i))
```

This commit applies the above to Assertions, e.g.:
```julia
julia> @macroexpand @Assert x != x "x == x: $x"
:(if x != x
      nothing
  else
      #= REPL[3]:36 =#
      var"#17#outline"(x) = begin
              $(Expr(:meta, :noinline))
              #= REPL[3]:36 =#
              (throw)((AssertionError)(((Main).Base.inferencebarrier((Main).Base.string))("x == x: $(x)")))
          end
      #= REPL[3]:38 =#
      var"#17#outline"(x)
  end)
```

This can improve performance for fast code that uses assertions, e.g.:

Before:
```julia
julia> @Btime Base.Sort.WithoutMissingVector($(Any[1]))[$1]
  3.041 ns (0 allocations: 0 bytes)
1
```
After:
```julia
julia> @Btime Base.Sort.WithoutMissingVector($(Any[1]))[$1]
  2.250 ns (0 allocations: 0 bytes)
1
```

The number of instructions in that function according to `@code_native`
(on an aarch64 M2 MacBook) reduced from ~90 to ~40.
@NHDaly NHDaly added the port-to-v1.10 This change should apply to Julia v1.10 builds label Jan 21, 2025
@NHDaly NHDaly changed the base branch from master to v1.10.2+RAI January 21, 2025 23:54
@NHDaly NHDaly added port-to-master This change should apply to all future Julia builds and removed port-to-v1.10 This change should apply to Julia v1.10 builds labels Jan 21, 2025
@NHDaly
Copy link
Member Author

NHDaly commented Jan 21, 2025

Oh, i did this all wrong, i'm sorry

@NHDaly NHDaly closed this Jan 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
port-to-master This change should apply to all future Julia builds
Projects
None yet
Development

Successfully merging this pull request may close these issues.