Skip to content

Commit 16aabfa

Browse files
committed
add new :total_but_may_throw utility setting for @assume_effects
This setting is particularly useful since it allows the compiler to evaluate a call of the applied method when all the call arguments are fully known, no matter if the call results in an error or not.
1 parent d96f010 commit 16aabfa

File tree

4 files changed

+24
-9
lines changed

4 files changed

+24
-9
lines changed

base/compiler/abstractinterpretation.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -715,7 +715,7 @@ function concrete_eval_eligible(interp::AbstractInterpreter,
715715
isoverlayed(method_table(interp)) && result.edge_effects.overlayed && return false
716716
return f !== nothing &&
717717
result.edge !== nothing &&
718-
is_total_or_error(result.edge_effects) &&
718+
is_concrete_eval_eligible(result.edge_effects) &&
719719
is_all_const_arg(arginfo)
720720
end
721721

base/compiler/types.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,13 @@ function Effects(e::Effects = EFFECTS_UNKNOWN;
7878
inbounds_taints_consistency)
7979
end
8080

81-
is_total_or_error(effects::Effects) =
81+
is_concrete_eval_eligible(effects::Effects) =
8282
effects.consistent === ALWAYS_TRUE &&
8383
effects.effect_free === ALWAYS_TRUE &&
8484
effects.terminates === ALWAYS_TRUE
8585

8686
is_total(effects::Effects) =
87-
is_total_or_error(effects) &&
87+
is_concrete_eval_eligible(effects) &&
8888
effects.nothrow === ALWAYS_TRUE
8989

9090
is_removable_if_unused(effects::Effects) =

base/expr.jl

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -512,11 +512,24 @@ This `setting` combines the following other assertions:
512512
- `:terminates_globally`
513513
and is a convenient shortcut.
514514
515+
---
516+
# `:total_but_may_throw`
517+
518+
This `setting` combines the following other assertions:
519+
- `:consistent`
520+
- `:effect_free`
521+
- `:terminates_globally`
522+
and is a convenient shortcut.
523+
515524
!!! note
516-
`@assume_effects :total` is similar to `@Base.pure` with the primary
525+
This setting is particularly useful since it allows the compiler to evaluate a call of
526+
the applied method when all the call arguments are fully known, no matter if the call
527+
results in an error or not.
528+
529+
`@assume_effects :total_but_may_throw` is similar to `Base.@pure` with the primary
517530
distinction that the `:consistent`-cy requirement applies world-age wise rather
518531
than globally as described above. However, in particular, a method annotated
519-
`@Base.pure` is always `:total`.
532+
`Base.@pure` should always be `:total` or `:total_but_may_throw`.
520533
"""
521534
macro assume_effects(args...)
522535
(consistent, effect_free, nothrow, terminates_globally, terminates_locally) =
@@ -537,12 +550,14 @@ macro assume_effects(args...)
537550
terminates_locally = true
538551
elseif setting === :total
539552
consistent = effect_free = nothrow = terminates_globally = true
553+
elseif setting === :total_but_may_throw
554+
consistent = effect_free = terminates_globally = true
540555
else
541556
throw(ArgumentError("@assume_effects $setting not supported"))
542557
end
543558
end
544559
ex = args[end]
545-
isa(ex, Expr) || throw(ArgumentError("Bad expression `$ex` in @constprop [settings] ex"))
560+
isa(ex, Expr) || throw(ArgumentError("Bad expression `$ex` in `@assume_effects [settings] ex`"))
546561
if ex.head === :macrocall && ex.args[1] == Symbol("@ccall")
547562
ex.args[1] = GlobalRef(Base, Symbol("@ccall_effects"))
548563
insert!(ex.args, 3, Core.Compiler.encode_effects_override(Core.Compiler.EffectsOverride(

test/compiler/inline.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1088,11 +1088,11 @@ recur_termination22(x) = x * recur_termination21(x-1)
10881088
recur_termination21(12) + recur_termination22(12)
10891089
end
10901090

1091-
const ___CONST_DICT___ = Dict{Any,Any}(:a => 1, :b => 2)
1092-
Base.@assume_effects :consistent :effect_free :terminates_globally consteval(
1091+
const ___CONST_DICT___ = Dict{Any,Any}(Symbol(c) => i for (i, c) in enumerate('a':'z'))
1092+
Base.@assume_effects :total_but_may_throw concrete_eval(
10931093
f, args...; kwargs...) = f(args...; kwargs...)
10941094
@test fully_eliminated() do
1095-
consteval(getindex, ___CONST_DICT___, :a)
1095+
concrete_eval(getindex, ___CONST_DICT___, :a)
10961096
end
10971097

10981098
# https://github.com/JuliaLang/julia/issues/44732

0 commit comments

Comments
 (0)