Skip to content

Commit

Permalink
Move EffectsOverride to expr.jl
Browse files Browse the repository at this point in the history
It makes sense that we originally added this to the compiler, but
these annotations are really a runtime feature that the compiler
simply reads to allow it to make additional assumptions. The runtime
should not semantically depend on the compiler for this, so
move these definitions to expr.jl. The practical effect of this
right now is that Base gains a second copy of this code.
Post #56128, the compiler will use the Base copy of this.

Split out from #56128.
  • Loading branch information
Keno committed Oct 16, 2024
1 parent 9844d85 commit 33b336d
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 78 deletions.
41 changes: 0 additions & 41 deletions base/compiler/compiler.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,47 +38,6 @@ convert(::Type{T}, x::T) where {T} = x
# Note that `@assume_effects` is available only after loading namedtuple.jl.
abstract type MethodTableView end
abstract type AbstractInterpreter end
struct EffectsOverride
consistent::Bool
effect_free::Bool
nothrow::Bool
terminates_globally::Bool
terminates_locally::Bool
notaskstate::Bool
inaccessiblememonly::Bool
noub::Bool
noub_if_noinbounds::Bool
consistent_overlay::Bool
nortcall::Bool
end
function EffectsOverride(
override::EffectsOverride =
EffectsOverride(false, false, false, false, false, false, false, false, false, false, false);
consistent::Bool = override.consistent,
effect_free::Bool = override.effect_free,
nothrow::Bool = override.nothrow,
terminates_globally::Bool = override.terminates_globally,
terminates_locally::Bool = override.terminates_locally,
notaskstate::Bool = override.notaskstate,
inaccessiblememonly::Bool = override.inaccessiblememonly,
noub::Bool = override.noub,
noub_if_noinbounds::Bool = override.noub_if_noinbounds,
consistent_overlay::Bool = override.consistent_overlay,
nortcall::Bool = override.nortcall)
return EffectsOverride(
consistent,
effect_free,
nothrow,
terminates_globally,
terminates_locally,
notaskstate,
inaccessiblememonly,
noub,
noub_if_noinbounds,
consistent_overlay,
nortcall)
end
const NUM_EFFECTS_OVERRIDES = 11 # sync with julia.h

# essential files and libraries
include("essentials.jl")
Expand Down
31 changes: 0 additions & 31 deletions base/compiler/effects.jl
Original file line number Diff line number Diff line change
Expand Up @@ -355,36 +355,5 @@ function decode_effects(e::UInt32)
_Bool((e >> 14) & 0x01))
end

function encode_effects_override(eo::EffectsOverride)
e = 0x0000
eo.consistent && (e |= (0x0001 << 0))
eo.effect_free && (e |= (0x0001 << 1))
eo.nothrow && (e |= (0x0001 << 2))
eo.terminates_globally && (e |= (0x0001 << 3))
eo.terminates_locally && (e |= (0x0001 << 4))
eo.notaskstate && (e |= (0x0001 << 5))
eo.inaccessiblememonly && (e |= (0x0001 << 6))
eo.noub && (e |= (0x0001 << 7))
eo.noub_if_noinbounds && (e |= (0x0001 << 8))
eo.consistent_overlay && (e |= (0x0001 << 9))
eo.nortcall && (e |= (0x0001 << 10))
return e
end

function decode_effects_override(e::UInt16)
return EffectsOverride(
!iszero(e & (0x0001 << 0)),
!iszero(e & (0x0001 << 1)),
!iszero(e & (0x0001 << 2)),
!iszero(e & (0x0001 << 3)),
!iszero(e & (0x0001 << 4)),
!iszero(e & (0x0001 << 5)),
!iszero(e & (0x0001 << 6)),
!iszero(e & (0x0001 << 7)),
!iszero(e & (0x0001 << 8)),
!iszero(e & (0x0001 << 9)),
!iszero(e & (0x0001 << 10)))
end

decode_statement_effects_override(ssaflag::UInt32) =
decode_effects_override(UInt16((ssaflag >> NUM_IR_FLAGS) & (1 << NUM_EFFECTS_OVERRIDES - 1)))
2 changes: 1 addition & 1 deletion base/experimental.jl
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,7 @@ macro consistent_overlay(mt, def)
inner = Base.unwrap_macrocalls(def)
is_function_def(inner) || error("@consistent_overlay requires a function definition")
overlay_def!(mt, inner)
override = Core.Compiler.EffectsOverride(; consistent_overlay=true)
override = Base.EffectsOverride(; consistent_overlay=true)
Base.pushmeta!(def::Expr, Base.form_purity_expr(override))
return esc(def)
end
Expand Down
79 changes: 76 additions & 3 deletions base/expr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -757,7 +757,7 @@ macro assume_effects(args...)
return esc(pushmeta!(lastex::Expr, form_purity_expr(override)))
elseif isexpr(lastex, :macrocall) && lastex.args[1] === Symbol("@ccall")
lastex.args[1] = GlobalRef(Base, Symbol("@ccall_effects"))
insert!(lastex.args, 3, Core.Compiler.encode_effects_override(override))
insert!(lastex.args, 3, encode_effects_override(override))
return esc(lastex)
end
override′ = compute_assumed_setting(override, lastex)
Expand All @@ -784,7 +784,49 @@ function compute_assumed_settings(settings)
return override
end

using Core.Compiler: EffectsOverride
struct EffectsOverride
consistent::Bool
effect_free::Bool
nothrow::Bool
terminates_globally::Bool
terminates_locally::Bool
notaskstate::Bool
inaccessiblememonly::Bool
noub::Bool
noub_if_noinbounds::Bool
consistent_overlay::Bool
nortcall::Bool
end

function EffectsOverride(
override::EffectsOverride =
EffectsOverride(false, false, false, false, false, false, false, false, false, false, false);
consistent::Bool = override.consistent,
effect_free::Bool = override.effect_free,
nothrow::Bool = override.nothrow,
terminates_globally::Bool = override.terminates_globally,
terminates_locally::Bool = override.terminates_locally,
notaskstate::Bool = override.notaskstate,
inaccessiblememonly::Bool = override.inaccessiblememonly,
noub::Bool = override.noub,
noub_if_noinbounds::Bool = override.noub_if_noinbounds,
consistent_overlay::Bool = override.consistent_overlay,
nortcall::Bool = override.nortcall)
return EffectsOverride(
consistent,
effect_free,
nothrow,
terminates_globally,
terminates_locally,
notaskstate,
inaccessiblememonly,
noub,
noub_if_noinbounds,
consistent_overlay,
nortcall)
end

const NUM_EFFECTS_OVERRIDES = 11 # sync with julia.h

function compute_assumed_setting(override::EffectsOverride, @nospecialize(setting), val::Bool=true)
if isexpr(setting, :call) && setting.args[1] === :(!)
Expand Down Expand Up @@ -826,9 +868,40 @@ function compute_assumed_setting(override::EffectsOverride, @nospecialize(settin
return nothing
end

function encode_effects_override(eo::EffectsOverride)
e = 0x0000
eo.consistent && (e |= (0x0001 << 0))
eo.effect_free && (e |= (0x0001 << 1))
eo.nothrow && (e |= (0x0001 << 2))
eo.terminates_globally && (e |= (0x0001 << 3))
eo.terminates_locally && (e |= (0x0001 << 4))
eo.notaskstate && (e |= (0x0001 << 5))
eo.inaccessiblememonly && (e |= (0x0001 << 6))
eo.noub && (e |= (0x0001 << 7))
eo.noub_if_noinbounds && (e |= (0x0001 << 8))
eo.consistent_overlay && (e |= (0x0001 << 9))
eo.nortcall && (e |= (0x0001 << 10))
return e
end

function decode_effects_override(e::UInt16)
return EffectsOverride(
!iszero(e & (0x0001 << 0)),
!iszero(e & (0x0001 << 1)),
!iszero(e & (0x0001 << 2)),
!iszero(e & (0x0001 << 3)),
!iszero(e & (0x0001 << 4)),
!iszero(e & (0x0001 << 5)),
!iszero(e & (0x0001 << 6)),
!iszero(e & (0x0001 << 7)),
!iszero(e & (0x0001 << 8)),
!iszero(e & (0x0001 << 9)),
!iszero(e & (0x0001 << 10)))
end

function form_purity_expr(override::EffectsOverride)
ex = Expr(:purity)
for i = 1:Core.Compiler.NUM_EFFECTS_OVERRIDES
for i = 1:NUM_EFFECTS_OVERRIDES
push!(ex.args, getfield(override, i))
end
return ex
Expand Down
2 changes: 1 addition & 1 deletion src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ typedef struct _jl_debuginfo_t {
jl_value_t *codelocs; // String // Memory{UInt8} // compressed info
} jl_debuginfo_t;

// the following mirrors `struct EffectsOverride` in `base/compiler/effects.jl`
// the following mirrors `struct EffectsOverride` in `base/expr.jl`
typedef union __jl_purity_overrides_t {
struct {
uint16_t ipo_consistent : 1;
Expand Down
2 changes: 1 addition & 1 deletion test/strings/basic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1236,7 +1236,7 @@ end
end
@test_throws ArgumentError Symbol("a\0a")

@test Base._string_n_override == Core.Compiler.encode_effects_override(Base.compute_assumed_settings((:total, :(!:consistent))))
@test Base._string_n_override == Base.encode_effects_override(Base.compute_assumed_settings((:total, :(!:consistent))))
end

@testset "Ensure UTF-8 DFA can never leave invalid state" begin
Expand Down

0 comments on commit 33b336d

Please sign in to comment.