Skip to content

Commit

Permalink
remove incomplete support for 1.7 entirely (#408)
Browse files Browse the repository at this point in the history
  • Loading branch information
aviatesk authored Nov 1, 2022
1 parent a27d7ec commit 97bdd20
Show file tree
Hide file tree
Showing 12 changed files with 39 additions and 348 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "JET"
uuid = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b"
authors = ["Shuhei Kadowaki <[email protected]>"]
version = "0.6.13"
version = "0.6.14"

[deps]
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
JET.jl employs Julia's type inference system to detect potential bugs.

!!! note
The latest version of JET requires Julia versions **1.7 and higher**;
The latest version of JET requires Julia versions **1.8** and higher;
JET is tested against [the current stable release](https://julialang.org/downloads/#current_stable_release) as well as [nightly version](https://julialang.org/downloads/nightlies/). \
Also note that JET deeply relies on the type inference routine implemented in [the Julia compiler](https://github.com/JuliaLang/julia/tree/master/base/compiler),
and so the analysis result can vary depending on your Julia version.
Expand Down
111 changes: 18 additions & 93 deletions src/JET.jl
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ import .CC:
switchtupleunion, tmerge, widenconst,

import Base:
@invoke, @invokelatest, IdSet, destructure_callex, parse_input_line, rewrap_unionall,
uniontypes, unwrap_unionall
@invoke, @invokelatest, @constprop, IdSet, default_tt, destructure_callex,
parse_input_line, rewrap_unionall, uniontypes, unwrap_unionall

import Base.Meta:
_parse_string, isexpr, lower
Expand Down Expand Up @@ -131,23 +131,7 @@ __init__() = foreach(@nospecialize(f)->f(), INIT_HOOKS)
# compat
# ------

# branch on https://github.com/JuliaLang/julia/pull/42082
const IS_AFTER_42082 = hasmethod(InferenceState, (InferenceResult, Symbol, AbstractInterpreter))

const IS_AFTER_42529 = isdefined(CC, :ArgInfo)
@static IS_AFTER_42529 && import .CC: ArgInfo

const IS_V18 = VERSION v"1.8-"
@static IS_V18 && import .CC: concrete_eval_eligible, concrete_eval_call

# branch on https://github.com/JuliaLang/julia/pull/42125
@static if isdefined(Base, Symbol("@constprop"))
import Base: @constprop
else
macro constprop(_, ex); esc(ex); end
end

@static @isdefined(LazyString) || include("strings/lazy.jl")
import .CC: ArgInfo, concrete_eval_eligible, concrete_eval_call, hasintersect

function anypush!(a::Vector{Any}, @nospecialize x...)
na = length(a)
Expand All @@ -159,13 +143,7 @@ function anypush!(a::Vector{Any}, @nospecialize x...)
return a
end

@static if isdefined(Core.Compiler, :hasintersect)
import .CC: hasintersect
else
hasintersect(@nospecialize(a), @nospecialize(b)) = typeintersect(a, b) !== Bottom
end

@static if !isdefined(@__MODULE__, :getglobal)
@static if !@isdefined(getglobal)
const getglobal = getfield
end

Expand Down Expand Up @@ -747,23 +725,17 @@ function analyze_method_instance!(analyzer::AbstractAnalyzer, mi::MethodInstance
)
result = InferenceResult(mi)

@static if IS_AFTER_42082
frame = InferenceState(result, #=cache=# :global, analyzer)
else
frame = InferenceState(result, #=cached=# true, analyzer)
end
frame = InferenceState(result, #=cache=# :global, analyzer)

isnothing(frame) && return analyzer, result

set_entry && set_entry!(analyzer, mi)
return analyze_frame!(analyzer, frame)
end

const CACHE_ARG_TYPE = IS_AFTER_42082 ? Symbol : Bool

function InferenceState(result::InferenceResult, cache::CACHE_ARG_TYPE, analyzer::AbstractAnalyzer)
function InferenceState(result::InferenceResult, cache::Symbol, analyzer::AbstractAnalyzer)
init_result!(analyzer, result) # set `JETResult` for succeeding JET analysis
return @invoke InferenceState(result::InferenceResult, cache::CACHE_ARG_TYPE, analyzer::AbstractInterpreter)
return @invoke InferenceState(result::InferenceResult, cache::Symbol, analyzer::AbstractInterpreter)
end

function analyze_frame!(analyzer::AbstractAnalyzer, frame::InferenceState)
Expand Down Expand Up @@ -1163,9 +1135,7 @@ function analyze_toplevel!(analyzer::AbstractAnalyzer, src::CodeInfo;
# toplevel frames don't really need to be cached, but still better to be optimized
# in order to get reasonable `LocalUndefVarErrorReport` and `UncaughtExceptionReport`
# NOTE and also, otherwise `typeinf_edge` won't add "toplevel-to-callee" edges
frame = (@static IS_AFTER_42082 ?
InferenceState(result, src, #=cache=# :global, analyzer) :
InferenceState(result, src, #=cached=# true, analyzer))::InferenceState
frame = InferenceState(result, src, #=cache=# :global, analyzer)::InferenceState

set_entry && set_entry!(analyzer, mi)
return analyze_frame!(analyzer, frame)
Expand Down Expand Up @@ -1220,34 +1190,14 @@ end
# resolve toplevel symbols (and other expressions like `:foreigncall`)
# so that the returned `CodeInfo` is eligible for abstractintepret and optimization
# TODO `jl_resolve_globals_in_ir` can throw, and we want to bypass it to `ToplevelErrorReport`
@static if VERSION v"1.8.0-DEV.421"
function resolve_toplevel_symbols!(mod::Module, src::CodeInfo)
newsrc = copy(src)
@ccall jl_resolve_globals_in_ir(
#=jl_array_t *stmts=# newsrc.code::Any,
#=jl_module_t *m=# mod::Any,
#=jl_svec_t *sparam_vals=# svec()::Any,
#=int binding_effects=# 0::Int)::Cvoid
return newsrc
end
else
# HACK before https://github.com/JuliaLang/julia/pull/42013, we need to go through
# the method definition pipeline to get the effect of `jl_resolve_globals_in_ir`
function resolve_toplevel_symbols!(mod::Module, src::CodeInfo)
sig = svec(
#=atypes=# svec(typeof(__toplevelf__)),
#=tvars=# svec(),
#=functionloc=# LineNumberNode(@__LINE__, @__FILE__))
# branching on https://github.com/JuliaLang/julia/pull/41137
method = (@static if isdefined(Core.Compiler, :OverlayMethodTable)
ccall(:jl_method_def, Any, (Any, Ptr{Cvoid}, Any, Any), sig, C_NULL, src, mod)
else
ccall(:jl_method_def, Cvoid, (Any, Any, Any), sig, src, mod)
only(methods(__toplevelf__))
end)::Method
return CC.uncompressed_ir(method)
end
function __toplevelf__ end
function resolve_toplevel_symbols!(mod::Module, src::CodeInfo)
newsrc = copy(src)
@ccall jl_resolve_globals_in_ir(
#=jl_array_t *stmts=# newsrc.code::Any,
#=jl_module_t *m=# mod::Any,
#=jl_svec_t *sparam_vals=# svec()::Any,
#=int binding_effects=# 0::Int)::Cvoid
return newsrc
end

# interactive
Expand Down Expand Up @@ -1293,22 +1243,6 @@ function report_call(@nospecialize(f), @nospecialize(types = default_tt(f)); jet
return report_call(tt; jetconfigs...)
end

@static if isdefined(Base, :default_tt)
import Base: default_tt
else
# returns argument tuple type which is supposed to be used for `code_typed` and its family;
# if there is a single method this functions returns the method argument signature,
# otherwise returns `Tuple` that doesn't match with any signature
function default_tt(@nospecialize(f))
ms = methods(f)
if length(ms) == 1
return Base.tuple_type_tail(only(ms).sig)
else
return Tuple
end
end
end

function report_call(@nospecialize(tt::Type{<:Tuple});
analyzer::Type{Analyzer} = JETAnalyzer,
source::Union{Nothing,AbstractString} = nothing,
Expand All @@ -1318,7 +1252,7 @@ function report_call(@nospecialize(tt::Type{<:Tuple});
analyzer, result = analyze_gf_by_type!(analyzer, tt)

if isnothing(source)
source = string(nameof(var"@report_call"), " ", sprint(show_tuple_as_call, Symbol(""), tt))
source = string(nameof(var"@report_call"), " ", sprint(Base.show_tuple_as_call, Symbol(""), tt))
end

return JETCallResult(result, analyzer, source; jetconfigs...)
Expand Down Expand Up @@ -1453,15 +1387,6 @@ macro test_call(ex0...)
end
end

get_exceptions() = @static if isdefined(Base, :current_exceptions)
Base.current_exceptions()
else
Base.catch_stack()
end
@static if !hasfield(Pass, :source)
Pass(test_type::Symbol, orig_expr, data, thrown, source) = Pass(test_type, orig_expr, data, thrown)
end

function test_exs(ex0, m, source)
analysis = InteractiveUtils.gen_call_with_extracted_types_and_kwargs(m, :report_call, ex0)
orig_expr = QuoteNode(
Expand All @@ -1476,7 +1401,7 @@ function test_exs(ex0, m, source)
end
catch err
isa(err, $InterruptException) && rethrow()
$Error(:test_error, $orig_expr, err, $get_exceptions(), $source)
$Error(:test_error, $orig_expr, err, $(Base.current_exceptions()), $source)
end) |> Base.remove_linenums!
return testres, orig_expr
end
Expand Down
32 changes: 1 addition & 31 deletions src/abstractinterpret/abstractanalyzer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ let
tuple_splat::Int = 32,
assume_fatal_throw::Bool = false,
)
elseif isdefined(CC, :mark_throw_blocks!)
else
kwargs = :(inlining::Bool = inlining_enabled(),
inline_cost_threshold::Int = 100,
inline_nonleaf_penalty::Int = 1000,
Expand All @@ -281,17 +281,6 @@ let
tuple_splat::Int = 32,
union_splitting::Int = 4,
)
else
kwargs = :(inlining::Bool = inlining_enabled(),
inline_cost_threshold::Int = 100,
inline_nonleaf_penalty::Int = 1000,
inline_tupleret_bonus::Int = 250,
inline_error_path_cost::Int = 20,
max_methods::Int = 3,
tuple_splat::Int = 32,
union_splitting::Int = 4,
unoptimize_throw_blocks::Bool = true,
)
end
kwargs_exs = Expr[]
names = Symbol[]
Expand Down Expand Up @@ -525,7 +514,6 @@ CC.may_compress(analyzer::AbstractAnalyzer) = false
CC.may_discard_trees(analyzer::AbstractAnalyzer) = false
CC.verbose_stmt_info(analyzer::AbstractAnalyzer) = false

@static if IS_AFTER_42082
let # overload `inlining_policy`
@static if isdefined(CC, :CallInfo)
sigs_ex = :(analyzer::AbstractAnalyzer,
Expand Down Expand Up @@ -555,24 +543,6 @@ let # overload `inlining_policy`
end
end
end
else # @static if IS_AFTER_42082
@doc """
inlining_policy(::AbstractAnalyzer) = jet_inlining_policy
jet_inlining_policy(@nospecialize(src)) -> source::Any
`jet_inlining_policy` implements `Core.Compiler.inlining_policy` for `AbstractAnalyzer`.
Since `AbstractAnalyzer` works on `InferenceResult` whose `src` field keeps
[`JETResult`](@ref) or [`JETCachedResult`](@ref), `jet_inlining_policy` forwards
their wrapped source to `Core.Compiler.default_inlining_policy`.
"""
CC.inlining_policy(::AbstractAnalyzer) = jet_inlining_policy
@inline function jet_inlining_policy(@nospecialize(src))
if isa(src, JETCachedResult)
src = src.src
end
return CC.default_inlining_policy(src)
end
end # @static if IS_AFTER_42082

# AbstractAnalyzer
# ================
Expand Down
44 changes: 6 additions & 38 deletions src/abstractinterpret/typeinfer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ function CC.builtin_tfunction(analyzer::AbstractAnalyzer,
if istoplevel_getproperty(sv)
ret = narrow_toplevel_getglobal(argtypes, ret)
end
elseif (@static isdefined(Core, :get_binding_type) && (f === Core.get_binding_type))
elseif f === Core.get_binding_type
if istoplevel(sv)
ret = narrow_toplevel_binding_type(argtypes, ret)
end
Expand Down Expand Up @@ -224,27 +224,13 @@ let # overload `abstract_call_method_with_const_args`
args_ex = :(analyzer::AbstractInterpreter,
result::MethodCallResult, f::Any, arginfo::ArgInfo, match::MethodMatch,
sv::InferenceState, invoketypes::Any)
elseif IS_V18
else
sigs_ex = :(analyzer::AbstractAnalyzer,
result::MethodCallResult, @nospecialize(f), arginfo::ArgInfo, match::MethodMatch,
sv::InferenceState)
args_ex = :(analyzer::AbstractInterpreter,
result::MethodCallResult, f::Any, arginfo::ArgInfo, match::MethodMatch,
sv::InferenceState)
elseif IS_AFTER_42529
sigs_ex = :(analyzer::AbstractAnalyzer,
result::MethodCallResult, @nospecialize(f), arginfo::ArgInfo, match::MethodMatch,
sv::InferenceState, va_override::Bool)
args_ex = :(analyzer::AbstractInterpreter,
result::MethodCallResult, f::Any, arginfo::ArgInfo, match::MethodMatch,
sv::InferenceState, va_override::Bool)
else
sigs_ex = :(analyzer::AbstractAnalyzer,
result::MethodCallResult, @nospecialize(f), argtypes::Argtypes, match::MethodMatch,
sv::InferenceState, va_override::Bool)
args_ex = :(analyzer::AbstractInterpreter,
result::MethodCallResult, f::Any, argtypes::Argtypes, match::MethodMatch,
sv::InferenceState, va_override::Bool)
end
@eval function CC.abstract_call_method_with_const_args($(sigs_ex.args...))
set_cacher!(analyzer, :abstract_call_method_with_const_args => sv.result)
Expand Down Expand Up @@ -286,13 +272,11 @@ let # overload `concrete_eval_call`
args_ex = :(analyzer::AbstractInterpreter,
f::Any, result::MethodCallResult, arginfo::ArgInfo, sv::InferenceState,
invokecall::Union{Nothing,CC.InvokeCall})
elseif IS_V18
else
sigs_ex = :(analyzer::AbstractAnalyzer,
@nospecialize(f), result::MethodCallResult, arginfo::ArgInfo, sv::InferenceState)
args_ex = :(analyzer::AbstractInterpreter,
f::Any, result::MethodCallResult, arginfo::ArgInfo, sv::InferenceState)
else
return # `concrete_eval_call` isn't defined for this case
end
@eval function CC.concrete_eval_call($(sigs_ex.args...))
ret = @invoke CC.concrete_eval_call($(args_ex.args...))
Expand All @@ -314,18 +298,12 @@ let # overload `abstract_call`
args_ex = :(analyzer::AbstractInterpreter, arginfo::ArgInfo, si::StmtInfo, sv::InferenceState,
max_methods::Int)
argtypes_ex = :(arginfo.argtypes)
elseif IS_AFTER_42529
else
sigs_ex = :(analyzer::AbstractAnalyzer, arginfo::ArgInfo, sv::InferenceState,
$(Expr(:kw, :(max_methods::Int), :(InferenceParams(analyzer).MAX_METHODS))))
args_ex = :(analyzer::AbstractInterpreter, arginfo::ArgInfo, sv::InferenceState,
max_methods::Int)
argtypes_ex = :(arginfo.argtypes)
else
sigs_ex = :(analyzer::AbstractAnalyzer, fargs::Union{Nothing,Vector{Any}}, argtypes::Argtypes, sv::InferenceState,
$(Expr(:kw, :(max_methods::Int), :(InferenceParams(analyzer).MAX_METHODS))))
args_ex = :(analyzer::AbstractInterpreter, fargs::Union{Nothing,Vector{Any}}, argtypes::Argtypes, sv::InferenceState,
max_methods::Int)
argtypes_ex = :argtypes
end
@eval function CC.abstract_call($(sigs_ex.args...))
ret = @invoke CC.abstract_call($(args_ex.args...))
Expand Down Expand Up @@ -548,13 +526,9 @@ function CC.transform_result_for_cache(analyzer::AbstractAnalyzer,
AbstractInterpreter, MethodInstance, WorldRange, InferenceResult))
inferred_result = @invoke transform_result_for_cache(analyzer::AbstractInterpreter,
linfo::MethodInstance, valid_worlds::WorldRange, result::InferenceResult)
elseif isdefined(CC, :Effects) && hasmethod(CC.transform_result_for_cache, (
AbstractInterpreter, MethodInstance, WorldRange, Any, CC.Effects))
inferred_result = @invoke transform_result_for_cache(analyzer::AbstractInterpreter,
linfo::MethodInstance, valid_worlds::WorldRange, result.src::Any, result.ipo_effects::CC.Effects)
else
inferred_result = @invoke transform_result_for_cache(analyzer::AbstractInterpreter,
linfo::MethodInstance, valid_worlds::WorldRange, result.src::Any)
linfo::MethodInstance, valid_worlds::WorldRange, result.src::Any, result.ipo_effects::CC.Effects)
end
return JETCachedResult(inferred_result, cache)
end
Expand Down Expand Up @@ -780,13 +754,7 @@ function CC._typeinf(analyzer::AbstractAnalyzer, frame::InferenceState)
if (@static VERSION v"1.9.0-DEV.1636" ?
(opt isa OptimizationState{typeof(analyzer)}) :
(opt isa OptimizationState))
@static if VERSION v"1.8.0-DEV.1425"
CC.optimize(analyzer, opt, OptimizationParams(analyzer), caller)
else
result_type = caller.result
@assert !(result_type isa LimitedAccuracy)
CC.optimize(analyzer, opt, OptimizationParams(analyzer), result_type)
end
CC.optimize(analyzer, opt, OptimizationParams(analyzer), caller)
# # COMBAK we may want to enable inlining ?
# if opt.const_api
# # XXX: The work in ir_to_codeinf! is essentially wasted. The only reason
Expand Down
Loading

2 comments on commit 97bdd20

@aviatesk
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/71404

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.6.14 -m "<description of version>" 97bdd2088991e2a7d83bc0a394eeced611645b3d
git push origin v0.6.14

Please sign in to comment.