Skip to content

Commit 68c8e5e

Browse files
committed
allow override of :nonoverlayed
1 parent fe554b7 commit 68c8e5e

File tree

10 files changed

+93
-39
lines changed

10 files changed

+93
-39
lines changed

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
#=:notaskstate=#true,
284284
#=:inaccessiblememonly=#true,
285285
#=:noub=#true,
286-
#=:noub_if_noinbounds=#false))
286+
#=:noub_if_noinbounds=#false,
287+
#=:nonoverlayed=#false))
287288
end
288289

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

base/compiler/abstractinterpretation.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2826,7 +2826,8 @@ function override_effects(effects::Effects, override::EffectsOverride)
28262826
inaccessiblememonly = override.inaccessiblememonly ? ALWAYS_TRUE : effects.inaccessiblememonly,
28272827
noub = override.noub ? ALWAYS_TRUE :
28282828
override.noub_if_noinbounds && effects.noub !== ALWAYS_TRUE ? NOUB_IF_NOINBOUNDS :
2829-
effects.noub)
2829+
effects.noub,
2830+
nonoverlayed = override.nonoverlayed ? true : effects.nonoverlayed)
28302831
end
28312832

28322833
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
@@ -47,10 +47,11 @@ struct EffectsOverride
4747
inaccessiblememonly::Bool
4848
noub::Bool
4949
noub_if_noinbounds::Bool
50+
nonoverlayed::Bool
5051
end
5152
function EffectsOverride(
5253
override::EffectsOverride =
53-
EffectsOverride(false, false, false, false, false, false, false, false, false);
54+
EffectsOverride(false, false, false, false, false, false, false, false, false, false);
5455
consistent::Bool = override.consistent,
5556
effect_free::Bool = override.effect_free,
5657
nothrow::Bool = override.nothrow,
@@ -59,7 +60,8 @@ function EffectsOverride(
5960
notaskstate::Bool = override.notaskstate,
6061
inaccessiblememonly::Bool = override.inaccessiblememonly,
6162
noub::Bool = override.noub,
62-
noub_if_noinbounds::Bool = override.noub_if_noinbounds)
63+
noub_if_noinbounds::Bool = override.noub_if_noinbounds,
64+
nonoverlayed::Bool = override.nonoverlayed)
6365
return EffectsOverride(
6466
consistent,
6567
effect_free,
@@ -69,9 +71,10 @@ function EffectsOverride(
6971
notaskstate,
7072
inaccessiblememonly,
7173
noub,
72-
noub_if_noinbounds)
74+
noub_if_noinbounds,
75+
nonoverlayed)
7376
end
74-
const NUM_EFFECTS_OVERRIDES = 9 # sync with julia.h
77+
const NUM_EFFECTS_OVERRIDES = 10 # sync with julia.h
7578

7679
# essential files and libraries
7780
include("essentials.jl")

base/compiler/effects.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@ function encode_effects_override(eo::EffectsOverride)
329329
eo.inaccessiblememonly && (e |= (0x0001 << 6))
330330
eo.noub && (e |= (0x0001 << 7))
331331
eo.noub_if_noinbounds && (e |= (0x0001 << 8))
332+
eo.nonoverlayed && (e |= (0x0001 << 9))
332333
return e
333334
end
334335

@@ -342,7 +343,8 @@ function decode_effects_override(e::UInt16)
342343
!iszero(e & (0x0001 << 5)),
343344
!iszero(e & (0x0001 << 6)),
344345
!iszero(e & (0x0001 << 7)),
345-
!iszero(e & (0x0001 << 8)))
346+
!iszero(e & (0x0001 << 8)),
347+
!iszero(e & (0x0001 << 9)))
346348
end
347349

348350
decode_statement_effects_override(ssaflag::UInt32) =

base/compiler/typeinfer.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,9 @@ function adjust_effects(ipo_effects::Effects, def::Method)
448448
elseif is_effect_overridden(override, :noub_if_noinbounds) && ipo_effects.noub !== ALWAYS_TRUE
449449
ipo_effects = Effects(ipo_effects; noub=NOUB_IF_NOINBOUNDS)
450450
end
451+
if is_effect_overridden(override, :nonoverlayed)
452+
ipo_effects = Effects(ipo_effects; nonoverlayed=true)
453+
end
451454
return ipo_effects
452455
end
453456

base/essentials.jl

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,8 @@ macro _total_meta()
201201
#=:notaskstate=#true,
202202
#=:inaccessiblememonly=#true,
203203
#=:noub=#true,
204-
#=:noub_if_noinbounds=#false))
204+
#=:noub_if_noinbounds=#false,
205+
#=:nonoverlayed=#false))
205206
end
206207
# can be used in place of `@assume_effects :foldable` (supposed to be used for bootstrapping)
207208
macro _foldable_meta()
@@ -214,7 +215,8 @@ macro _foldable_meta()
214215
#=:notaskstate=#true,
215216
#=:inaccessiblememonly=#true,
216217
#=:noub=#true,
217-
#=:noub_if_noinbounds=#false))
218+
#=:noub_if_noinbounds=#false,
219+
#=:nonoverlayed=#false))
218220
end
219221
# can be used in place of `@assume_effects :terminates_locally` (supposed to be used for bootstrapping)
220222
macro _terminates_locally_meta()
@@ -227,7 +229,8 @@ macro _terminates_locally_meta()
227229
#=:notaskstate=#false,
228230
#=:inaccessiblememonly=#false,
229231
#=:noub=#false,
230-
#=:noub_if_noinbounds=#false))
232+
#=:noub_if_noinbounds=#false,
233+
#=:nonoverlayed=#false))
231234
end
232235
# can be used in place of `@assume_effects :terminates_globally` (supposed to be used for bootstrapping)
233236
macro _terminates_globally_meta()
@@ -240,7 +243,8 @@ macro _terminates_globally_meta()
240243
#=:notaskstate=#false,
241244
#=:inaccessiblememonly=#false,
242245
#=:noub=#false,
243-
#=:noub_if_noinbounds=#false))
246+
#=:noub_if_noinbounds=#false,
247+
#=:nonoverlayed=#false))
244248
end
245249
# can be used in place of `@assume_effects :terminates_globally :notaskstate` (supposed to be used for bootstrapping)
246250
macro _terminates_globally_notaskstate_meta()
@@ -253,7 +257,8 @@ macro _terminates_globally_notaskstate_meta()
253257
#=:notaskstate=#true,
254258
#=:inaccessiblememonly=#false,
255259
#=:noub=#false,
256-
#=:noub_if_noinbounds=#false))
260+
#=:noub_if_noinbounds=#false,
261+
#=:nonoverlayed=#false))
257262
end
258263
# can be used in place of `@assume_effects :terminates_globally :noub` (supposed to be used for bootstrapping)
259264
macro _terminates_globally_noub_meta()
@@ -266,7 +271,8 @@ macro _terminates_globally_noub_meta()
266271
#=:notaskstate=#false,
267272
#=:inaccessiblememonly=#false,
268273
#=:noub=#true,
269-
#=:noub_if_noinbounds=#false))
274+
#=:noub_if_noinbounds=#false,
275+
#=:nonoverlayed=#false))
270276
end
271277
# can be used in place of `@assume_effects :effect_free :terminates_locally` (supposed to be used for bootstrapping)
272278
macro _effect_free_terminates_locally_meta()
@@ -279,7 +285,8 @@ macro _effect_free_terminates_locally_meta()
279285
#=:notaskstate=#false,
280286
#=:inaccessiblememonly=#false,
281287
#=:noub=#false,
282-
#=:noub_if_noinbounds=#false))
288+
#=:noub_if_noinbounds=#false,
289+
#=:nonoverlayed=#false))
283290
end
284291
# can be used in place of `@assume_effects :nothrow :noub` (supposed to be used for bootstrapping)
285292
macro _nothrow_noub_meta()
@@ -292,7 +299,8 @@ macro _nothrow_noub_meta()
292299
#=:notaskstate=#false,
293300
#=:inaccessiblememonly=#false,
294301
#=:noub=#true,
295-
#=:noub_if_noinbounds=#false))
302+
#=:noub_if_noinbounds=#false,
303+
#=:nonoverlayed=#false))
296304
end
297305
# can be used in place of `@assume_effects :nothrow` (supposed to be used for bootstrapping)
298306
macro _nothrow_meta()
@@ -305,7 +313,8 @@ macro _nothrow_meta()
305313
#=:notaskstate=#false,
306314
#=:inaccessiblememonly=#false,
307315
#=:noub=#false,
308-
#=:noub_if_noinbounds=#false))
316+
#=:noub_if_noinbounds=#false,
317+
#=:nonoverlayed=#false))
309318
end
310319
# can be used in place of `@assume_effects :nothrow` (supposed to be used for bootstrapping)
311320
macro _noub_meta()
@@ -318,7 +327,8 @@ macro _noub_meta()
318327
#=:notaskstate=#false,
319328
#=:inaccessiblememonly=#false,
320329
#=:noub=#true,
321-
#=:noub_if_noinbounds=#false))
330+
#=:noub_if_noinbounds=#false,
331+
#=:nonoverlayed=#false))
322332
end
323333
# can be used in place of `@assume_effects :notaskstate` (supposed to be used for bootstrapping)
324334
macro _notaskstate_meta()
@@ -331,7 +341,8 @@ macro _notaskstate_meta()
331341
#=:notaskstate=#true,
332342
#=:inaccessiblememonly=#false,
333343
#=:noub=#false,
334-
#=:noub_if_noinbounds=#false))
344+
#=:noub_if_noinbounds=#false,
345+
#=:nonoverlayed=#false))
335346
end
336347
# can be used in place of `@assume_effects :noub_if_noinbounds` (supposed to be used for bootstrapping)
337348
macro _noub_if_noinbounds_meta()
@@ -344,7 +355,8 @@ macro _noub_if_noinbounds_meta()
344355
#=:notaskstate=#false,
345356
#=:inaccessiblememonly=#false,
346357
#=:noub=#false,
347-
#=:noub_if_noinbounds=#true))
358+
#=:noub_if_noinbounds=#true,
359+
#=:nonoverlayed=#false))
348360
end
349361

350362
# another version of inlining that propagates an inbounds context

base/expr.jl

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ CodeInfo(
479479
!!! compat "Julia 1.10"
480480
The usage within a function body requires at least Julia 1.10.
481481
482-
!!! compact "Julia 1.11"
482+
!!! compat "Julia 1.11"
483483
The code block annotation requires at least Julia 1.11.
484484
485485
!!! warning
@@ -505,6 +505,7 @@ The following `setting`s are supported.
505505
- `:inaccessiblememonly`
506506
- `:noub`
507507
- `:noub_if_noinbounds`
508+
- `:nonoverlayed`
508509
- `:foldable`
509510
- `:removable`
510511
- `:total`
@@ -673,6 +674,10 @@ The `:noub` setting asserts that the method will not execute any undefined behav
673674
any other effect assertions (such as `:consistent` or `:effect_free`) as well, but we do
674675
not model this, and they assume the absence of undefined behavior.
675676
677+
---
678+
## `:nonoverlayed`
679+
TODO.
680+
676681
---
677682
## `:foldable`
678683
@@ -793,6 +798,8 @@ function compute_assumed_setting(override::EffectsOverride, @nospecialize(settin
793798
return EffectsOverride(override; noub = val)
794799
elseif setting === :noub_if_noinbounds
795800
return EffectsOverride(override; noub_if_noinbounds = val)
801+
elseif setting === :nonoverlayed
802+
return EffectsOverride(override; nonoverlayed = val)
796803
elseif setting === :foldable
797804
consistent = effect_free = terminates_globally = noub = val
798805
return EffectsOverride(override; consistent, effect_free, terminates_globally, noub)
@@ -810,10 +817,11 @@ function compute_assumed_setting(override::EffectsOverride, @nospecialize(settin
810817
end
811818

812819
function form_purity_expr(override::EffectsOverride)
813-
return Expr(:purity,
814-
override.consistent, override.effect_free, override.nothrow,
815-
override.terminates_globally, override.terminates_locally, override.notaskstate,
816-
override.inaccessiblememonly, override.noub, override.noub_if_noinbounds)
820+
ex = Expr(:purity)
821+
for i = 1:Core.Compiler.NUM_EFFECTS_OVERRIDES
822+
push!(ex.args, getfield(override, i))
823+
end
824+
return ex
817825
end
818826

819827
"""

src/julia.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,11 +279,12 @@ typedef union __jl_purity_overrides_t {
279279
uint16_t ipo_inaccessiblememonly : 1;
280280
uint16_t ipo_noub : 1;
281281
uint16_t ipo_noub_if_noinbounds : 1;
282+
uint16_t ipo_nonoverlayed : 1;
282283
} overrides;
283284
uint16_t bits;
284285
} _jl_purity_overrides_t;
285286

286-
#define NUM_EFFECTS_OVERRIDES 9
287+
#define NUM_EFFECTS_OVERRIDES 10
287288
#define NUM_IR_FLAGS 13
288289

289290
// This type describes a single function body

src/method.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,7 @@ jl_code_info_t *jl_new_code_info_from_ir(jl_expr_t *ir)
475475
li->purity.overrides.ipo_inaccessiblememonly = jl_unbox_bool(jl_exprarg(ma, 6));
476476
li->purity.overrides.ipo_noub = jl_unbox_bool(jl_exprarg(ma, 7));
477477
li->purity.overrides.ipo_noub_if_noinbounds = jl_unbox_bool(jl_exprarg(ma, 8));
478+
li->purity.overrides.ipo_nonoverlayed = jl_unbox_bool(jl_exprarg(ma, 9));
478479
}
479480
}
480481
else

test/compiler/AbstractInterpreter.jl

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ using Base.Experimental: @MethodTable, @overlay
3131
end
3232

3333
@newinterp MTOverlayInterp
34-
@MethodTable OverlayedMT
35-
CC.method_table(interp::MTOverlayInterp) = CC.OverlayMethodTable(CC.get_inference_world(interp), OverlayedMT)
34+
@MethodTable OVERLAY_MT
35+
CC.method_table(interp::MTOverlayInterp) = CC.OverlayMethodTable(CC.get_inference_world(interp), OVERLAY_MT)
3636

3737
function CC.add_remark!(interp::MTOverlayInterp, ::CC.InferenceState, remark)
3838
if interp.meta !== nothing
@@ -44,7 +44,7 @@ end
4444

4545
struct StrangeSinError end
4646
strangesin(x) = sin(x)
47-
@overlay OverlayedMT strangesin(x::Float64) =
47+
@overlay OVERLAY_MT strangesin(x::Float64) =
4848
iszero(x) ? throw(StrangeSinError()) : x < 0 ? nothing : cos(x)
4949

5050
# inference should use the overlayed method table
@@ -102,7 +102,7 @@ end |> only === Float64
102102

103103
# not fully covered overlay method match
104104
overlay_match(::Any) = nothing
105-
@overlay OverlayedMT overlay_match(::Int) = missing
105+
@overlay OVERLAY_MT overlay_match(::Int) = missing
106106
@test Base.return_types((Any,); interp=MTOverlayInterp()) do x
107107
overlay_match(x)
108108
end |> only === Union{Nothing,Missing}
@@ -134,11 +134,33 @@ Base.@assume_effects :total totalcall(f, args...) = f(args...)
134134
end
135135
end |> only === Nothing
136136

137+
# override `:native_executable` to allow concrete-eval for overlay-ed methods
138+
Base.@assume_effects :foldable function gpucompiler384(x::Int)
139+
1 < x < 20 || error("x is too big")
140+
return factorial(x)
141+
end
142+
@overlay OVERLAY_MT Base.@assume_effects :foldable :nonoverlayed function gpucompiler384(x::Int)
143+
1 < x < 20 || raise_on_gpu("x is too big")
144+
return factorial(x)
145+
end
146+
@noinline raise_on_gpu(x) = #=do something with GPU=# error(x)
147+
call_gpucompiler384(x) = gpucompiler384(x)
148+
149+
@test Base.infer_effects(gpucompiler384, (Int,); interp=MTOverlayInterp()) |> Core.Compiler.is_nonoverlayed
150+
@test Base.infer_effects(call_gpucompiler384, (Int,); interp=MTOverlayInterp()) |> Core.Compiler.is_nonoverlayed
151+
152+
@test Base.infer_return_type(; interp=MTOverlayInterp()) do
153+
Val(gpucompiler384(3))
154+
end == Val{6}
155+
@test Base.infer_return_type(; interp=MTOverlayInterp()) do
156+
Val(call_gpucompiler384(3))
157+
end == Val{6}
158+
137159
# GPUCompiler needs accurate inference through kwfunc with the overlay of `Core.throw_inexacterror`
138160
# https://github.com/JuliaLang/julia/issues/48097
139161
@newinterp Issue48097Interp
140-
@MethodTable Issue48097MT
141-
CC.method_table(interp::Issue48097Interp) = CC.OverlayMethodTable(CC.get_inference_world(interp), Issue48097MT)
162+
@MethodTable ISSUE_48097_MT
163+
CC.method_table(interp::Issue48097Interp) = CC.OverlayMethodTable(CC.get_inference_world(interp), ISSUE_48097_MT)
142164
CC.InferenceParams(::Issue48097Interp) = CC.InferenceParams(; unoptimize_throw_blocks=false)
143165
function CC.concrete_eval_eligible(interp::Issue48097Interp,
144166
@nospecialize(f), result::CC.MethodCallResult, arginfo::CC.ArgInfo, sv::CC.AbsIntState)
@@ -150,34 +172,34 @@ function CC.concrete_eval_eligible(interp::Issue48097Interp,
150172
end
151173
return ret
152174
end
153-
@overlay Issue48097MT @noinline Core.throw_inexacterror(f::Symbol, ::Type{T}, val) where {T} = return
175+
@overlay ISSUE_48097_MT @noinline Core.throw_inexacterror(f::Symbol, ::Type{T}, val) where {T} = return
154176
issue48097(; kwargs...) = return 42
155177
@test_broken fully_eliminated(; interp=Issue48097Interp(), retval=42) do
156178
issue48097(; a=1f0, b=1.0)
157179
end
158180

159181
# Should not concrete-eval overlayed methods in semi-concrete interpretation
160182
@newinterp OverlaySinInterp
161-
@MethodTable OverlaySinMT
162-
CC.method_table(interp::OverlaySinInterp) = CC.OverlayMethodTable(CC.get_inference_world(interp), OverlaySinMT)
183+
@MethodTable OVERLAY_SIN_MT
184+
CC.method_table(interp::OverlaySinInterp) = CC.OverlayMethodTable(CC.get_inference_world(interp), OVERLAY_SIN_MT)
163185
overlay_sin1(x) = error("Not supposed to be called.")
164-
@overlay OverlaySinMT overlay_sin1(x) = cos(x)
165-
@overlay OverlaySinMT Base.sin(x::Union{Float32,Float64}) = overlay_sin1(x)
186+
@overlay OVERLAY_SIN_MT overlay_sin1(x) = cos(x)
187+
@overlay OVERLAY_SIN_MT Base.sin(x::Union{Float32,Float64}) = overlay_sin1(x)
166188
let oc = Base.code_ircode(; interp=OverlaySinInterp()) do
167189
sin(0.)
168190
end |> only |> first |> Core.OpaqueClosure
169191
@test oc() == cos(0.)
170192
end
171-
@overlay OverlaySinMT Base.sin(x::Union{Float32,Float64}) = @noinline overlay_sin1(x)
193+
@overlay OVERLAY_SIN_MT Base.sin(x::Union{Float32,Float64}) = @noinline overlay_sin1(x)
172194
let oc = Base.code_ircode(; interp=OverlaySinInterp()) do
173195
sin(0.)
174196
end |> only |> first |> Core.OpaqueClosure
175197
@test oc() == cos(0.)
176198
end
177199
_overlay_sin2(x) = error("Not supposed to be called.")
178-
@overlay OverlaySinMT _overlay_sin2(x) = cos(x)
200+
@overlay OVERLAY_SIN_MT _overlay_sin2(x) = cos(x)
179201
overlay_sin2(x) = _overlay_sin2(x)
180-
@overlay OverlaySinMT Base.sin(x::Union{Float32,Float64}) = @noinline overlay_sin2(x)
202+
@overlay OVERLAY_SIN_MT Base.sin(x::Union{Float32,Float64}) = @noinline overlay_sin2(x)
181203
let oc = Base.code_ircode(; interp=OverlaySinInterp()) do
182204
sin(0.)
183205
end |> only |> first |> Core.OpaqueClosure

0 commit comments

Comments
 (0)