Skip to content

Commit 0e42398

Browse files
authored
Backports release 1.11 (#55344)
Backported PRs: - [x] #54962 <!-- Add timing to precompile trace compile --> - [x] #55180 <!-- compress jit debuginfo for easy memory savings --> - [x] #54919 <!-- Fix annotated join with non-concrete eltype iters --> - [x] #55013 <!-- [docs] change docstring to match code --> - [x] #55017 <!-- TOML: Make `Dates` a type parameter --> - [x] #54033 <!-- Fix a bug in `stack`'s DimensionMismatch error message --> - [x] #55242 <!-- fix at-main docstring to not code quote a compat box --> - [x] #55261 <!-- Make `jl_*affinity` tests more portable --> - [x] #54736 <!-- specificity: ensure fast-path in `sub/eq_msp` handle missing `UnionAll` wrapper correctly. --> - [x] #55299 <!-- typeintersect: fix bounds merging during inner `intersect_all`. --> - [x] #55302 <!-- Add `lbt_forwarded_funcs()` to debug LBT forwarding issues --> - [x] #55148 <!-- Random: Mark unexported public symbols as public --> - [x] #55303 <!-- avoid overflowing show for OffsetArrays around typemax --> - [x] #55317 <!-- Restrict argument to `isleapyear(::Integer)` --> - [x] #55327 <!-- Profile: Fix stdlib paths --> - [x] #55330 <!-- [libblastrampoline] Bump to v5.11.0 --> - [x] #55310 <!-- Preserve structure in scaling triangular matrices by NaN --> - [x] #55329 <!-- mapreduce: don't inbounds unknown functions --> - [x] #55356 <!-- Profile: close files when assembling heap snapshot --> - [x] #55371 <!-- Fix tr for block SymTridiagonal --> - [x] #55307 <!-- Make REPL.TerminalMenus public --> - [x] #55362 <!-- inference: fix missing LimitedAccuracy markers --> - [x] #55306 <!-- AllocOpt: Fix stack lowering where alloca continas boxed and unboxed data --> - [x] #55395 <!-- fix #55389: type-unstable `join` --> - [x] #55226 <!-- re-add `unsafe_convert` for Reinterpret and Reshaped array --> - [x] #55405 <!-- handle unbound vars in NTuple fields --> - [x] #55365 <!-- ml-matches: ensure all methods are included --> - [x] #55428 <!-- codegen: move undef freeze before promotion point --> - [x] #55419 <!-- `stale_cachefile`: handle if the expected cache file is missing --> - [x] #55470 <!-- Add push! implementation for AbstractArray depending only on resize! --> - [x] #55483 <!-- fix hierarchy level of "API reference" in `Dates` documentation --> - [x] #55268 <!-- simplify complex atanh and remove singularity perturbation --> - [x] #55441 <!-- fix Event to use normal Condition variable --> - [x] #55413 <!-- subtyping: fast path for lhs union and rhs typevar --> - [x] #55492 <!-- build: add missing dependencies for expmap --> - [x] #55507 <!-- Fix fast getptls ccall lowering. --> - [x] #55424 <!-- add missing clamp function for IOBuffer --> - [x] #55504 <!-- Update symmetric docstring to reflect the type of uplo --> - [x] #55107 <!-- Make the memory GEP an inbounds GEP since the bounds check has happened somewhere else --> - [x] #55411 <!-- Vendor the terminfo database for use with base/terminfo.jl --> - [x] #55452 <!-- Do not load `ScopedValues` with `using` --> - [x] #55407 <!-- Remove deprecated non string API for LLVM pass pipeline and parse all options --> - [x] #55461 <!-- 🤖 [master] Bump the StyledStrings stdlib from d7496d2 to f6035eb --> - [x] #55433 <!-- Backport #55407 to 1.11 --> - [x] #55225 <!-- [1.11 backport] trace-compile: don't generate `precompile` statements for OpaqueClosure methods (#55072) --> - [x] #55212 <!-- Make `Base.depwarn()` public --> - [x] #552 - [x] #55052 <!-- Fix `(l/r)mul!` with `Diagonal`/`Bidiagonal` --> - [x] #55251 <!-- Restrict binary ops for Diagonal and Symmetric to Number eltypes -->95 <!-- LAPACK: Aggressive constprop to concretely infer syev!/syevd! --> - [x] #55522 <!-- Fix tr for Symmetric/Hermitian block matrices --> Need manual backport: - [x] #55342 <!-- Ensure bidiagonal setindex! does not read indices in error message --> Contains multiple commits, manual intervention needed: - [ ] #55336 <!-- codegen: take gc roots (and alloca alignment) more seriously --> Non-merged PRs with backport label: - [ ] #55506 <!-- Fix indexing in _mapreducedim for OffsetArrays --> - [ ] #55500 <!-- make jl_thread_suspend_and_get_state safe --> - [ ] #55499 <!-- propagate the terminal's `displaysize` to the `IOContext` used by the REPL --> - [ ] #55458 <!-- Allow for generically extracting unannotated string --> - [ ] #55457 <!-- Make AnnotateChar equality consider annotations --> - [ ] #55453 <!-- Privatise the annotations API, for StyledStrings --> - [ ] #55443 <!-- Add test for upper/lower/titlecase and fix call --> - [ ] #55355 <!-- relocation: account for trailing path separator in depot paths --> - [ ] #55220 <!-- `isfile_casesensitive` fixes on Windows --> - [ ] #55169 <!-- `propertynames` for SVD respects private argument --> - [ ] #54457 <!-- Make `String(::Memory)` copy --> - [ ] #53957 <!-- tweak how filtering is done for what packages should be precompiled --> - [ ] #51479 <!-- prevent code loading from lookin in the versioned environment when building Julia --> - [ ] #50813 <!-- More doctests for Sockets and capitalization fix --> - [ ] #50157 <!-- improve docs for `@inbounds` and `Base.@propagate_inbounds` --> - [ ] #41244 <!-- Fix shell `cd` error when working dir has been deleted -->
2 parents 34c3a63 + 13d440d commit 0e42398

File tree

127 files changed

+1638
-795
lines changed

Some content is hidden

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

127 files changed

+1638
-795
lines changed

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,10 @@ endif
398398
# Install appdata file
399399
mkdir -p $(DESTDIR)$(datarootdir)/appdata/
400400
$(INSTALL_F) $(JULIAHOME)/contrib/julia.appdata.xml $(DESTDIR)$(datarootdir)/appdata/
401+
# Install terminal info database
402+
ifneq ($(WITH_TERMINFO),0)
403+
cp -R -L $(build_datarootdir)/terminfo $(DESTDIR)$(datarootdir)
404+
endif
401405

402406
# Update RPATH entries and JL_SYSTEM_IMAGE_PATH if $(private_libdir_rel) != $(build_private_libdir_rel)
403407
ifneq ($(private_libdir_rel),$(build_private_libdir_rel))

NEWS.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ Multi-threading changes
6363
* `Threads.@threads` now supports the `:greedy` scheduler, intended for non-uniform workloads ([#52096]).
6464
* A new public (but unexported) struct `Base.Lockable{T, L<:AbstractLock}` makes it easy to bundle a resource and its lock together ([#52898]).
6565

66+
Build system changes
67+
--------------------
68+
69+
* There is a new `Makefile` to build Julia and LLVM using the profile-guided and link-time optimizations (PGO and LTO) strategies, see `contrib/pgo-lto/Makefile` ([#45641]).
70+
6671
New library functions
6772
---------------------
6873

@@ -202,6 +207,9 @@ External dependencies
202207
203208
* The libuv library has been updated from a base of v1.44.2 to v1.48.0 ([#49937]).
204209
* `tput` is no longer called to check terminal capabilities; it has been replaced with a pure-Julia terminfo parser ([#50797]).
210+
- The terminal info database, `terminfo`, is now vendored by default, providing a better
211+
REPL user experience when `terminfo` is not available on the system. Julia can be built
212+
without vendoring the database using the Makefile option `WITH_TERMINFO=0`. ([#55411])
205213
206214
Tooling Improvements
207215
--------------------
@@ -220,6 +228,7 @@ Tooling Improvements
220228
[#42593]: https://github.com/JuliaLang/julia/issues/42593
221229
[#43845]: https://github.com/JuliaLang/julia/issues/43845
222230
[#45156]: https://github.com/JuliaLang/julia/issues/45156
231+
[#45641]: https://github.com/JuliaLang/julia/issues/45641
223232
[#46501]: https://github.com/JuliaLang/julia/issues/46501
224233
[#47354]: https://github.com/JuliaLang/julia/issues/47354
225234
[#47679]: https://github.com/JuliaLang/julia/issues/47679

base/Base.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,6 @@ include("weakkeydict.jl")
399399

400400
# ScopedValues
401401
include("scopedvalues.jl")
402-
using .ScopedValues
403402

404403
# metaprogramming
405404
include("meta.jl")

base/abstractarray.jl

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2985,7 +2985,7 @@ end
29852985
@inline function _stack_size_check(x, ax1::Tuple)
29862986
if _iterator_axes(x) != ax1
29872987
uax1 = map(UnitRange, ax1)
2988-
uaxN = map(UnitRange, axes(x))
2988+
uaxN = map(UnitRange, _iterator_axes(x))
29892989
throw(DimensionMismatch(
29902990
LazyString("stack expects uniform slices, got axes(x) == ", uaxN, " while first had ", uax1)))
29912991
end
@@ -3497,13 +3497,45 @@ julia> map(+, [1 2; 3 4], [1,10,100,1000], zeros(3,1)) # iterates until 3rd is
34973497
"""
34983498
map(f, it, iters...) = collect(Generator(f, it, iters...))
34993499

3500+
# Generic versions of push! for AbstractVector
3501+
# These are specialized further for Vector for faster resizing and setindexing
3502+
function push!(a::AbstractVector{T}, item) where T
3503+
# convert first so we don't grow the array if the assignment won't work
3504+
itemT = item isa T ? item : convert(T, item)::T
3505+
new_length = length(a) + 1
3506+
resize!(a, new_length)
3507+
a[new_length] = itemT
3508+
return a
3509+
end
3510+
3511+
# specialize and optimize the single argument case
3512+
function push!(a::AbstractVector{Any}, @nospecialize x)
3513+
new_length = length(a) + 1
3514+
resize!(a, new_length)
3515+
a[new_length] = x
3516+
return a
3517+
end
3518+
function push!(a::AbstractVector{Any}, @nospecialize x...)
3519+
@_terminates_locally_meta
3520+
na = length(a)
3521+
nx = length(x)
3522+
resize!(a, na + nx)
3523+
for i = 1:nx
3524+
a[na+i] = x[i]
3525+
end
3526+
return a
3527+
end
3528+
35003529
# multi-item push!, pushfirst! (built on top of type-specific 1-item version)
35013530
# (note: must not cause a dispatch loop when 1-item case is not defined)
35023531
push!(A, a, b) = push!(push!(A, a), b)
35033532
push!(A, a, b, c...) = push!(push!(A, a, b), c...)
35043533
pushfirst!(A, a, b) = pushfirst!(pushfirst!(A, b), a)
35053534
pushfirst!(A, a, b, c...) = pushfirst!(pushfirst!(A, c...), a, b)
35063535

3536+
# sizehint! does not nothing by default
3537+
sizehint!(a::AbstractVector, _) = a
3538+
35073539
## hashing AbstractArray ##
35083540

35093541
const hash_abstractarray_seed = UInt === UInt64 ? 0x7e2d6fb6448beb77 : 0xd4514ce5

base/boot.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,8 @@ macro _foldable_meta()
283283
#=:inaccessiblememonly=#true,
284284
#=:noub=#true,
285285
#=:noub_if_noinbounds=#false,
286-
#=:consistent_overlay=#false))
286+
#=:consistent_overlay=#false,
287+
#=:nortcall=#true))
287288
end
288289

289290
macro inline() Expr(:meta, :inline) end

base/client.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -608,10 +608,10 @@ module MyApp
608608
end
609609
const main = MyApp.main
610610
# `julia` Will *NOT* execute MyApp.main unless there is a separate `@main` annotation in `Main`
611+
```
611612
612613
!!! compat "Julia 1.11"
613614
This macro is new in Julia 1.11. At present, the precise semantics of `@main` are still subject to change.
614-
```
615615
"""
616616
macro main(args...)
617617
if !isempty(args)

base/cmd.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,7 @@ function cmd_gen(parsed)
482482
end
483483
end
484484

485-
@assume_effects :effect_free :terminates_globally :noub function cmd_gen(
485+
@assume_effects :foldable !:consistent function cmd_gen(
486486
parsed::Tuple{Vararg{Tuple{Vararg{Union{String, SubString{String}}}}}}
487487
)
488488
return @invoke cmd_gen(parsed::Any)

base/compiler/abstractinterpretation.jl

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -605,13 +605,23 @@ function abstract_call_method(interp::AbstractInterpreter,
605605
end
606606
add_remark!(interp, sv, washardlimit ? RECURSION_MSG_HARDLIMIT : RECURSION_MSG)
607607
# TODO (#48913) implement a proper recursion handling for irinterp:
608-
# This works just because currently the `:terminate` condition guarantees that
609-
# irinterp doesn't fail into unresolved cycles, but it's not a good solution.
608+
# This works just because currently the `:terminate` condition usually means this is unreachable here
609+
# for irinterp because there are not unresolved cycles, but it's not a good solution.
610610
# We should revisit this once we have a better story for handling cycles in irinterp.
611-
if isa(topmost, InferenceState)
611+
if isa(sv, InferenceState)
612+
# since the hardlimit is against the edge to the parent frame,
613+
# we should try to poison the whole edge, not just the topmost frame
612614
parentframe = frame_parent(topmost)
613-
if isa(sv, InferenceState) && isa(parentframe, InferenceState)
614-
poison_callstack!(sv, parentframe === nothing ? topmost : parentframe)
615+
while !isa(parentframe, InferenceState)
616+
# attempt to find a parent frame that can handle this LimitedAccuracy result correctly
617+
# so we don't try to cache this incomplete intermediate result
618+
parentframe === nothing && break
619+
parentframe = frame_parent(parentframe)
620+
end
621+
if isa(parentframe, InferenceState)
622+
poison_callstack!(sv, parentframe)
623+
elseif isa(topmost, InferenceState)
624+
poison_callstack!(sv, topmost)
615625
end
616626
end
617627
# n.b. this heuristic depends on the non-local state, so we must record the limit later
@@ -887,7 +897,7 @@ function concrete_eval_eligible(interp::AbstractInterpreter,
887897
end
888898
end
889899
mi = result.edge
890-
if mi !== nothing && is_foldable(effects)
900+
if mi !== nothing && is_foldable(effects, #=check_rtcall=#true)
891901
if f !== nothing && is_all_const_arg(arginfo, #=start=#2)
892902
if (is_nonoverlayed(interp) || is_nonoverlayed(effects) ||
893903
# Even if overlay methods are involved, when `:consistent_overlay` is
@@ -2778,8 +2788,9 @@ function override_effects(effects::Effects, override::EffectsOverride)
27782788
notaskstate = override.notaskstate ? true : effects.notaskstate,
27792789
inaccessiblememonly = override.inaccessiblememonly ? ALWAYS_TRUE : effects.inaccessiblememonly,
27802790
noub = override.noub ? ALWAYS_TRUE :
2781-
(override.noub_if_noinbounds && effects.noub !== ALWAYS_TRUE) ? NOUB_IF_NOINBOUNDS :
2782-
effects.noub)
2791+
(override.noub_if_noinbounds && effects.noub !== ALWAYS_TRUE) ? NOUB_IF_NOINBOUNDS :
2792+
effects.noub,
2793+
nortcall = override.nortcall ? true : effects.nortcall)
27832794
end
27842795

27852796
isdefined_globalref(g::GlobalRef) = !iszero(ccall(:jl_globalref_boundp, Cint, (Any,), g))

base/compiler/compiler.jl

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,11 @@ struct EffectsOverride
4848
noub::Bool
4949
noub_if_noinbounds::Bool
5050
consistent_overlay::Bool
51+
nortcall::Bool
5152
end
5253
function EffectsOverride(
5354
override::EffectsOverride =
54-
EffectsOverride(false, false, false, false, false, false, false, false, false, false);
55+
EffectsOverride(false, false, false, false, false, false, false, false, false, false, false);
5556
consistent::Bool = override.consistent,
5657
effect_free::Bool = override.effect_free,
5758
nothrow::Bool = override.nothrow,
@@ -61,7 +62,8 @@ function EffectsOverride(
6162
inaccessiblememonly::Bool = override.inaccessiblememonly,
6263
noub::Bool = override.noub,
6364
noub_if_noinbounds::Bool = override.noub_if_noinbounds,
64-
consistent_overlay::Bool = override.consistent_overlay)
65+
consistent_overlay::Bool = override.consistent_overlay,
66+
nortcall::Bool = override.nortcall)
6567
return EffectsOverride(
6668
consistent,
6769
effect_free,
@@ -72,9 +74,10 @@ function EffectsOverride(
7274
inaccessiblememonly,
7375
noub,
7476
noub_if_noinbounds,
75-
consistent_overlay)
77+
consistent_overlay,
78+
nortcall)
7679
end
77-
const NUM_EFFECTS_OVERRIDES = 10 # sync with julia.h
80+
const NUM_EFFECTS_OVERRIDES = 11 # sync with julia.h
7881

7982
# essential files and libraries
8083
include("essentials.jl")

base/compiler/effects.jl

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ following meanings:
5858
methods are `:consistent` with their non-overlayed original counterparts
5959
(see [`Base.@assume_effects`](@ref) for the exact definition of `:consistenct`-cy).
6060
* `ALWAYS_FALSE`: this method may invoke overlayed methods.
61+
- `nortcall::Bool`: this method does not call `Core.Compiler.return_type`,
62+
and it is guaranteed that any other methods this method might call also do not call
63+
`Core.Compiler.return_type`.
6164
6265
Note that the representations above are just internal implementation details and thus likely
6366
to change in the future. See [`Base.@assume_effects`](@ref) for more detailed explanation
@@ -103,6 +106,9 @@ The output represents the state of different effect properties in the following
103106
- `+o` (green): `ALWAYS_TRUE`
104107
- `-o` (red): `ALWAYS_FALSE`
105108
- `?o` (yellow): `CONSISTENT_OVERLAY`
109+
9. `:nortcall` (`r`):
110+
- `+r` (green): `true`
111+
- `-r` (red): `false`
106112
"""
107113
struct Effects
108114
consistent::UInt8
@@ -113,6 +119,7 @@ struct Effects
113119
inaccessiblememonly::UInt8
114120
noub::UInt8
115121
nonoverlayed::UInt8
122+
nortcall::Bool
116123
function Effects(
117124
consistent::UInt8,
118125
effect_free::UInt8,
@@ -121,7 +128,8 @@ struct Effects
121128
notaskstate::Bool,
122129
inaccessiblememonly::UInt8,
123130
noub::UInt8,
124-
nonoverlayed::UInt8)
131+
nonoverlayed::UInt8,
132+
nortcall::Bool)
125133
return new(
126134
consistent,
127135
effect_free,
@@ -130,7 +138,8 @@ struct Effects
130138
notaskstate,
131139
inaccessiblememonly,
132140
noub,
133-
nonoverlayed)
141+
nonoverlayed,
142+
nortcall)
134143
end
135144
end
136145

@@ -160,10 +169,10 @@ const NOUB_IF_NOINBOUNDS = 0x01 << 1
160169
# :nonoverlayed bits
161170
const CONSISTENT_OVERLAY = 0x01 << 1
162171

163-
const EFFECTS_TOTAL = Effects(ALWAYS_TRUE, ALWAYS_TRUE, true, true, true, ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE)
164-
const EFFECTS_THROWS = Effects(ALWAYS_TRUE, ALWAYS_TRUE, false, true, true, ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE)
165-
const EFFECTS_UNKNOWN = Effects(ALWAYS_FALSE, ALWAYS_FALSE, false, false, false, ALWAYS_FALSE, ALWAYS_FALSE, ALWAYS_TRUE) # unknown mostly, but it's not overlayed at least (e.g. it's not a call)
166-
const _EFFECTS_UNKNOWN = Effects(ALWAYS_FALSE, ALWAYS_FALSE, false, false, false, ALWAYS_FALSE, ALWAYS_FALSE, ALWAYS_FALSE) # unknown really
172+
const EFFECTS_TOTAL = Effects(ALWAYS_TRUE, ALWAYS_TRUE, true, true, true, ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE, true)
173+
const EFFECTS_THROWS = Effects(ALWAYS_TRUE, ALWAYS_TRUE, false, true, true, ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE, true)
174+
const EFFECTS_UNKNOWN = Effects(ALWAYS_FALSE, ALWAYS_FALSE, false, false, false, ALWAYS_FALSE, ALWAYS_FALSE, ALWAYS_TRUE, false) # unknown mostly, but it's not overlayed at least (e.g. it's not a call)
175+
const _EFFECTS_UNKNOWN = Effects(ALWAYS_FALSE, ALWAYS_FALSE, false, false, false, ALWAYS_FALSE, ALWAYS_FALSE, ALWAYS_FALSE, false) # unknown really
167176

168177
function Effects(effects::Effects = _EFFECTS_UNKNOWN;
169178
consistent::UInt8 = effects.consistent,
@@ -173,7 +182,8 @@ function Effects(effects::Effects = _EFFECTS_UNKNOWN;
173182
notaskstate::Bool = effects.notaskstate,
174183
inaccessiblememonly::UInt8 = effects.inaccessiblememonly,
175184
noub::UInt8 = effects.noub,
176-
nonoverlayed::UInt8 = effects.nonoverlayed)
185+
nonoverlayed::UInt8 = effects.nonoverlayed,
186+
nortcall::Bool = effects.nortcall)
177187
return Effects(
178188
consistent,
179189
effect_free,
@@ -182,7 +192,8 @@ function Effects(effects::Effects = _EFFECTS_UNKNOWN;
182192
notaskstate,
183193
inaccessiblememonly,
184194
noub,
185-
nonoverlayed)
195+
nonoverlayed,
196+
nortcall)
186197
end
187198

188199
function is_better_effects(new::Effects, old::Effects)
@@ -247,6 +258,11 @@ function is_better_effects(new::Effects, old::Effects)
247258
elseif new.nonoverlayed != old.nonoverlayed
248259
return false
249260
end
261+
if new.nortcall
262+
any_improved |= !old.nortcall
263+
elseif new.nortcall != old.nortcall
264+
return false
265+
end
250266
return any_improved
251267
end
252268

@@ -259,7 +275,8 @@ function merge_effects(old::Effects, new::Effects)
259275
merge_effectbits(old.notaskstate, new.notaskstate),
260276
merge_effectbits(old.inaccessiblememonly, new.inaccessiblememonly),
261277
merge_effectbits(old.noub, new.noub),
262-
merge_effectbits(old.nonoverlayed, new.nonoverlayed))
278+
merge_effectbits(old.nonoverlayed, new.nonoverlayed),
279+
merge_effectbits(old.nortcall, new.nortcall))
263280
end
264281

265282
function merge_effectbits(old::UInt8, new::UInt8)
@@ -279,16 +296,18 @@ is_inaccessiblememonly(effects::Effects) = effects.inaccessiblememonly === ALWAY
279296
is_noub(effects::Effects) = effects.noub === ALWAYS_TRUE
280297
is_noub_if_noinbounds(effects::Effects) = effects.noub === NOUB_IF_NOINBOUNDS
281298
is_nonoverlayed(effects::Effects) = effects.nonoverlayed === ALWAYS_TRUE
299+
is_nortcall(effects::Effects) = effects.nortcall
282300

283301
# implies `is_notaskstate` & `is_inaccessiblememonly`, but not explicitly checked here
284-
is_foldable(effects::Effects) =
302+
is_foldable(effects::Effects, check_rtcall::Bool=false) =
285303
is_consistent(effects) &&
286304
(is_noub(effects) || is_noub_if_noinbounds(effects)) &&
287305
is_effect_free(effects) &&
288-
is_terminates(effects)
306+
is_terminates(effects) &&
307+
(!check_rtcall || is_nortcall(effects))
289308

290-
is_foldable_nothrow(effects::Effects) =
291-
is_foldable(effects) &&
309+
is_foldable_nothrow(effects::Effects, check_rtcall::Bool=false) =
310+
is_foldable(effects, check_rtcall) &&
292311
is_nothrow(effects)
293312

294313
# TODO add `is_noub` here?
@@ -318,7 +337,8 @@ function encode_effects(e::Effects)
318337
((e.notaskstate % UInt32) << 7) |
319338
((e.inaccessiblememonly % UInt32) << 8) |
320339
((e.noub % UInt32) << 10) |
321-
((e.nonoverlayed % UInt32) << 12)
340+
((e.nonoverlayed % UInt32) << 12) |
341+
((e.nortcall % UInt32) << 14)
322342
end
323343

324344
function decode_effects(e::UInt32)
@@ -330,7 +350,8 @@ function decode_effects(e::UInt32)
330350
_Bool((e >> 7) & 0x01),
331351
UInt8((e >> 8) & 0x03),
332352
UInt8((e >> 10) & 0x03),
333-
UInt8((e >> 12) & 0x03))
353+
UInt8((e >> 12) & 0x03),
354+
_Bool((e >> 14) & 0x01))
334355
end
335356

336357
function encode_effects_override(eo::EffectsOverride)
@@ -345,6 +366,7 @@ function encode_effects_override(eo::EffectsOverride)
345366
eo.noub && (e |= (0x0001 << 7))
346367
eo.noub_if_noinbounds && (e |= (0x0001 << 8))
347368
eo.consistent_overlay && (e |= (0x0001 << 9))
369+
eo.nortcall && (e |= (0x0001 << 10))
348370
return e
349371
end
350372

@@ -359,7 +381,8 @@ function decode_effects_override(e::UInt16)
359381
!iszero(e & (0x0001 << 6)),
360382
!iszero(e & (0x0001 << 7)),
361383
!iszero(e & (0x0001 << 8)),
362-
!iszero(e & (0x0001 << 9)))
384+
!iszero(e & (0x0001 << 9)),
385+
!iszero(e & (0x0001 << 10)))
363386
end
364387

365388
decode_statement_effects_override(ssaflag::UInt32) =

0 commit comments

Comments
 (0)