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

RFC: Effect Preconditions - or - the future of @inbounds #50641

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion base/abstractarraymath.jl
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ function repeat_outer(a::AbstractMatrix, (m,n)::NTuple{2, Any})
R = d:d+p-1
for i=1:m
c = (i-1)*o+1
@inbounds b[c:c+o-1, R] = a
b[c:c+o-1, R] = a
end
end
return b
Expand Down
8 changes: 4 additions & 4 deletions base/boot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ export
# type reflection
<:, typeof, isa, typeassert,
# method reflection
applicable, invoke,
applicable, invoke, invoke_split_effects,
# constants
nothing, Main

Expand Down Expand Up @@ -439,12 +439,12 @@ function CodeInstance(
mi::MethodInstance, @nospecialize(rettype), @nospecialize(inferred_const),
@nospecialize(inferred), const_flags::Int32, min_world::UInt, max_world::UInt,
ipo_effects::UInt32, effects::UInt32, @nospecialize(argescapes#=::Union{Nothing,Vector{ArgEscapeInfo}}=#),
relocatability::UInt8)
relocatability::UInt8, effect_assumptions::UInt32)
return ccall(:jl_new_codeinst, Ref{CodeInstance},
(Any, Any, Any, Any, Int32, UInt, UInt, UInt32, UInt32, Any, UInt8),
(Any, Any, Any, Any, Int32, UInt, UInt, UInt32, UInt32, Any, UInt8, UInt32),
mi, rettype, inferred_const, inferred, const_flags, min_world, max_world,
ipo_effects, effects, argescapes,
relocatability)
relocatability, effect_assumptions)
end
GlobalRef(m::Module, s::Symbol) = ccall(:jl_module_globalref, Ref{GlobalRef}, (Any, Any), m, s)
Module(name::Symbol=:anonymous, std_imports::Bool=true, default_names::Bool=true) = ccall(:jl_f_new_module, Ref{Module}, (Any, Bool, Bool), name, std_imports, default_names)
Expand Down
37 changes: 37 additions & 0 deletions base/compiler/abstractinterpretation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1969,6 +1969,43 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f),
return abstract_apply(interp, argtypes, si, sv, max_methods)
elseif f === invoke
return abstract_invoke(interp, arginfo, si, sv)
elseif f === invoke_split_effects
# First perform inference as usual. We may not need to use the precondition logic
# at all, (e.g. if we get a constant).
new_arginfo = ArgInfo(arginfo.fargs === nothing ? nothing : arginfo.fargs[3:end],
arginfo.argtypes[3:end])
r = abstract_call(interp, new_arginfo, si, sv, max_methods)
# Find applicable preconditions that we may be able to use
which = arginfo.argtypes[2]
if isa(which, Const)
if isa(r.info, MethodMatchInfo) && length(r.info.results) == 1 && which.val === :nothrow
# Check for user-defined preconditions
match = r.info.results[1]
m = match.method

for i = 1:2:length(m.preconditions)
i + 1 <= length(m.preconditions) || break

cond = m.preconditions[1]
check = m.preconditions[2]

isa(cond, EffectsOverride) || continue

# TODO: Should depend on `which`
cond.nothrow || continue

check_arginfo = ArgInfo(nothing,
Any[Const(check), arginfo.argtypes[3:end]...])
rcheck = abstract_call(interp, check_arginfo, StmtInfo(true), sv, max_methods)
rcheck.rt === Bool || continue
is_foldable_nothrow(rcheck.effects) || continue

# TODO: What to do if multiple preconditions match
return CallMeta(r.rt, r.effects, InvokeSplitEffectsInfo(r.info, check, cond, rcheck.info))
end
end
end
return r
elseif f === modifyfield!
return abstract_modifyfield!(interp, argtypes, si, sv)
elseif f === Core.finalizer
Expand Down
4 changes: 2 additions & 2 deletions base/compiler/cicache.jl
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ WorldView(wvc::WorldView, wr::WorldRange) = WorldView(wvc.cache, wr)
WorldView(wvc::WorldView, args...) = WorldView(wvc.cache, args...)

function haskey(wvc::WorldView{InternalCodeCache}, mi::MethodInstance)
return ccall(:jl_rettype_inferred, Any, (Any, UInt, UInt), mi, first(wvc.worlds), last(wvc.worlds)) !== nothing
return ccall(:jl_rettype_inferred, Any, (Any, UInt, UInt, UInt32), mi, first(wvc.worlds), last(wvc.worlds), 0) !== nothing
end

function get(wvc::WorldView{InternalCodeCache}, mi::MethodInstance, default)
r = ccall(:jl_rettype_inferred, Any, (Any, UInt, UInt), mi, first(wvc.worlds), last(wvc.worlds))
r = ccall(:jl_rettype_inferred, Any, (Any, UInt, UInt, UInt32), mi, first(wvc.worlds), last(wvc.worlds), 0)
if r === nothing
return default
end
Expand Down
1 change: 1 addition & 0 deletions base/compiler/effects.jl
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ struct EffectsOverride
notaskstate::Bool
inaccessiblememonly::Bool
end
EffectsOverride() = decode_effects_override(0x00)

function encode_effects_override(eo::EffectsOverride)
e = 0x00
Expand Down
Loading