From a9426a47c0b9762a32f122fc8873f85a98c8bab4 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Mon, 21 Feb 2022 15:04:08 +0900 Subject: [PATCH] update with 1.8 (#325) fixes #322, #324 closes #323 --- src/JET.jl | 3 +++ src/abstractinterpret/typeinfer.jl | 31 ++++++++++++++++-------- src/analyzers/jetanalyzer.jl | 38 +++++++++++++++++++++++++++++- 3 files changed, 61 insertions(+), 11 deletions(-) diff --git a/src/JET.jl b/src/JET.jl index 0f8ec4adb..56394a5bd 100644 --- a/src/JET.jl +++ b/src/JET.jl @@ -228,6 +228,9 @@ const IS_AFTER_42082 = hasmethod(InferenceState, (InferenceResult, Symbol, Abstr const IS_AFTER_42529 = isdefined(CC, :ArgInfo) IS_AFTER_42529 && import .CC: ArgInfo +const IS_V18 = VERSION ≥ v"1.8" +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 diff --git a/src/abstractinterpret/typeinfer.jl b/src/abstractinterpret/typeinfer.jl index 3a392309f..d3145a1e0 100644 --- a/src/abstractinterpret/typeinfer.jl +++ b/src/abstractinterpret/typeinfer.jl @@ -190,27 +190,43 @@ end end end +@static if IS_V18 +function CC.abstract_call_method_with_const_args(analyzer::AbstractAnalyzer, result::MethodCallResult, + @nospecialize(f), arginfo::ArgInfo, match::MethodMatch, + sv::InferenceState) + set_cacher!(analyzer, :abstract_call_method_with_const_args => sv.result) + const_result = + @invoke CC.abstract_call_method_with_const_args(analyzer::AbstractInterpreter, result::MethodCallResult, + @nospecialize(f), arginfo::ArgInfo, match::MethodMatch, + sv::InferenceState) + # we should make sure we reset the cacher because at this point we may have not hit + # `CC.cache_lookup(linfo::MethodInstance, given_argtypes::Argtypes, cache::JETLocalCache)` + set_cacher!(analyzer, nothing) + if const_result !== nothing + # successful constant prop', we also need to update reports + collect_callee_reports!(analyzer, sv) + end + return const_result +end +else # @static if IS_V18 function CC.abstract_call_method_with_const_args(analyzer::AbstractAnalyzer, result::MethodCallResult, @nospecialize(f), arginfo::(@static IS_AFTER_42529 ? ArgInfo : Argtypes), match::MethodMatch, sv::InferenceState, va_override::Bool) set_cacher!(analyzer, :abstract_call_method_with_const_args => sv.result) - const_result = @invoke CC.abstract_call_method_with_const_args(analyzer::AbstractInterpreter, result::MethodCallResult, @nospecialize(f), arginfo::(@static IS_AFTER_42529 ? ArgInfo : Argtypes), match::MethodMatch, sv::InferenceState, va_override::Bool) - # we should make sure we reset the cacher because at this point we may have not hit # `CC.cache_lookup(linfo::MethodInstance, given_argtypes::Argtypes, cache::JETLocalCache)` set_cacher!(analyzer, nothing) - if const_result !== nothing # successful constant prop', we also need to update reports collect_callee_reports!(analyzer, sv) end - return const_result end +end # @static if IS_V18 @static if IS_AFTER_42529 function CC.abstract_call(analyzer::AbstractAnalyzer, arginfo::ArgInfo, @@ -405,12 +421,7 @@ function CC.cache_result!(analyzer::AbstractAnalyzer, result::InferenceResult) # TODO: also don't store inferred code if we've previously decided to interpret this function if !already_inferred inferred_result = transform_result_for_cache(analyzer, linfo, valid_worlds, result) - @static if VERSION ≥ v"1.8.0-DEV.1434" - relocatability = isa(inferred_result, Vector{UInt8}) ? inferred_result[end] : UInt8(0) - CC.setindex!(code_cache(analyzer), CodeInstance(result, inferred_result, valid_worlds, relocatability), linfo) - else - CC.setindex!(code_cache(analyzer), CodeInstance(result, inferred_result, valid_worlds), linfo) - end + CC.setindex!(code_cache(analyzer), CodeInstance(result, inferred_result, valid_worlds), linfo) end unlock_mi_inference(analyzer, linfo) nothing diff --git a/src/analyzers/jetanalyzer.jl b/src/analyzers/jetanalyzer.jl index 1efa32549..092e4be33 100644 --- a/src/analyzers/jetanalyzer.jl +++ b/src/analyzers/jetanalyzer.jl @@ -454,7 +454,43 @@ function CC.add_call_backedges!(analyzer::JETAnalyzer, @nospecialize(rettype), e end end -# this overload isn't necessary after https://github.com/JuliaLang/julia/pull/41882 +@static if IS_V18 +# just fallback to the constant-prop' handling +function CC.concrete_eval_eligible(analyzer::JETAnalyzer, + @nospecialize(f), result::MethodCallResult, arginfo::ArgInfo, sv::InferenceState) + return false +end +# # TODO make ConstError behave like UncaughtExceptionReport +# function CC.concrete_eval_call(analyzer::JETAnalyzer, +# @nospecialize(f), result::MethodCallResult, arginfo::ArgInfo, sv::InferenceState) +# CC.concrete_eval_eligible(analyzer, f, result, arginfo, sv) || return nothing +# empty!(get_reports(analyzer, sv.result)) +# args = CC.collect_const_args(arginfo) +# try +# value = Core._call_in_world_total(get_world_counter(analyzer), f, args...) +# if CC.is_inlineable_constant(value) || CC.call_result_unused(sv) +# # If the constant is not inlineable, still do the const-prop, since the +# # code that led to the creation of the Const may be inlineable in the same +# # circumstance and may be optimizable. +# return CC.ConstCallResults(Const(value), CC.ConstResult(result.edge, value), CC.EFFECTS_TOTAL) +# end +# catch err +# ReportPass(analyzer)(ConstError, analyzer, sv, err) +# # The evaulation threw. By :consistent-cy, we're guaranteed this would have happened at runtime +# return CC.ConstCallResults(Union{}, CC.ConstResult(result.edge::MethodInstance), result.edge_effects) +# end +# end +# @reportdef struct ConstError <: InferenceErrorReport +# @nospecialize(err) +# end +# get_msg(::Type{ConstError}, sv::InferenceState, @nospecialize(err)) = +# "will throw `$(typeof(err))`" +# function (::SoundBasicPass)(::Type{ConstError}, analyzer::AbstractAnalyzer, sv::InferenceState, @nospecialize(err)) +# isa(err, ErrorException) && return false +# add_new_report!(analyzer, sv.result, ConstError(sv, err)) +# return true +# end +end # @static if IS_V18 @doc """ const_prop_entry_heuristic(analyzer::JETAnalyzer, result::MethodCallResult, sv::InferenceState)