Skip to content
Merged
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
10 changes: 6 additions & 4 deletions Manifest.toml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions src/analysis/compiler.jl
Original file line number Diff line number Diff line change
Expand Up @@ -717,7 +717,8 @@ end
record_ir!(debug_config, "pre_incidence_propagation", ir)

# TODO better work here?
method_info = CC.MethodInfo(#=propagate_inbounds=#true, nothing)
(nargs, isva) = isa(mi.def, Method) ? (mi.def.nargs, mi.def.isva) : (0, false)
method_info = CC.SpecInfo(nargs, isva, #=propagate_inbounds=#true, nothing)
min_world = world = get_inference_world(interp)
max_world = get_world_counter()
if caller !== nothing
Expand All @@ -726,7 +727,7 @@ end
analysis_interp = DAEInterpreter(interp; var_to_diff, var_kind, eq_kind, in_analysis=interp.ipo_analysis_mode)
irsv = CC.IRInterpretationState(analysis_interp, method_info, ir, mi, argtypes,
world, min_world, max_world)
ultimate_rt, _ = CC._ir_abstract_constant_propagation(analysis_interp, irsv; externally_refined)
ultimate_rt, _ = CC.ir_abstract_constant_propagation(analysis_interp, irsv; externally_refined)
record_ir!(debug_config, "incidence_propagation", ir)

# Encountering a `ddt` during abstract interpretation can add variables,
Expand All @@ -745,7 +746,7 @@ end
# recalculate domtree (inference could have changed the cfg)
domtree = CC.construct_domtree(ir.cfg.blocks)

# We use the _ir_abstract_constant_propagation pass for three things:
# We use the ir_abstract_constant_propagation pass for three things:
# 1. To establish incidence
# 2. To constant propagate scope information that may not have been
# available at inference time
Expand Down
97 changes: 48 additions & 49 deletions src/analysis/interpreter.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ using .CC: AbstractInterpreter, NativeInterpreter, InferenceParams, Optimization
StmtInfo, MethodCallResult, ConstCallResults, ConstPropResult, MethodTableView,
CachedMethodTable, InternalMethodTable, OverlayMethodTable, CallMeta, CallInfo,
IRCode, LazyDomtree, IRInterpretationState, set_inlineable!, block_for_inst,
BitSetBoundedMinPrioritySet, AbsIntState
BitSetBoundedMinPrioritySet, AbsIntState, Future
using Base: IdSet
using StateSelection: DiffGraph

Expand Down Expand Up @@ -282,13 +282,13 @@ widenincidence(@nospecialize(x)) = x
if length(argtypes) == 2
xarg = argtypes[2]
if isa(xarg, Union{Incidence, Const})
return structural_inc_ddt(interp.var_to_diff, interp.var_kind, xarg)
return Future{CallMeta}(structural_inc_ddt(interp.var_to_diff, interp.var_kind, xarg))
end
end
end
if interp.in_analysis && !isa(f, Core.Builtin) && !isa(f, Core.IntrinsicFunction)
# We don't want to do new inference here
return CallMeta(Any, Any, CC.Effects(), CC.NoCallInfo())
return Future{CallMeta}(CallMeta(Any, Any, CC.Effects(), CC.NoCallInfo()))
end
ret = @invoke CC.abstract_call_known(interp::AbstractInterpreter, f::Any,
arginfo::ArgInfo, si::StmtInfo, sv::AbsIntState, max_methods::Int)
Expand All @@ -305,27 +305,27 @@ widenincidence(@nospecialize(x)) = x
end
end
arginfo = ArgInfo(arginfo.fargs, map(widenincidence, arginfo.argtypes))
r = Diffractor.fwd_abstract_call_gf_by_type(interp, f, arginfo, si, sv, ret)
r !== nothing && return r
return ret
return Diffractor.fwd_abstract_call_gf_by_type(interp, f, arginfo, si, sv, ret)
end

@override function CC.abstract_call_method(interp::DAEInterpreter,
method::Method, @nospecialize(sig), sparams::SimpleVector, hardlimit::Bool, si::StmtInfo, sv::InferenceState)
ret = @invoke CC.abstract_call_method(interp::AbstractInterpreter,
mret = @invoke CC.abstract_call_method(interp::AbstractInterpreter,
method::Method, sig::Any, sparams::SimpleVector, hardlimit::Bool, si::StmtInfo, sv::InferenceState)
edge = ret.edge
if edge !== nothing
cache = CC.get(CC.code_cache(interp), edge, nothing)
if cache !== nothing
src = @atomic :monotonic cache.inferred
if isa(src, DAECache)
info = src.info
merge_daeinfo!(interp, sv.result, info)
return Future{MethodCallResult}(mret, interp, sv) do ret, interp, sv
edge = ret.edge
if edge !== nothing
cache = CC.get(CC.code_cache(interp), edge, nothing)
if cache !== nothing
src = @atomic :monotonic cache.inferred
if isa(src, DAECache)
info = src.info
merge_daeinfo!(interp, sv.result, info)
end
end
end
return ret
end
return ret
end

@override function CC.const_prop_call(interp::DAEInterpreter,
Expand Down Expand Up @@ -443,9 +443,9 @@ end

# TODO propagate debug configurations here
@override function CC.optimize(interp::DAEInterpreter, opt::OptimizationState, caller::InferenceResult)
ir = CC.run_passes_ipo_safe(opt.src, opt, caller)
ir = CC.run_passes_ipo_safe(opt.src, opt)
ir = run_dae_passes(interp, ir)
CC.ipo_dataflow_analysis!(interp, ir, caller)
CC.ipo_dataflow_analysis!(interp, opt, ir, caller)
if interp.ipo_analysis_mode
result = ipo_dae_analysis!(interp, ir, caller.linfo, caller)
if result !== nothing
Expand Down Expand Up @@ -524,14 +524,10 @@ end
src === nothing && return nothing
(; inferred, ir) = src::DAECache
(isa(inferred, CodeInfo) && isa(ir, IRCode)) || return nothing
method_info = CC.MethodInfo(inferred)
method_info = CC.SpecInfo(inferred)
ir = copy(ir)
(; min_world, max_world) = inferred
if Base.__has_internal_change(v"1.12-alpha", :codeinfonargs)
argtypes = CC.va_process_argtypes(CC.optimizer_lattice(interp), argtypes, inferred.nargs, inferred.isva)
elseif VERSION >= v"1.12.0-DEV.341"
argtypes = CC.va_process_argtypes(CC.optimizer_lattice(interp), argtypes, mi)
end
argtypes = CC.va_process_argtypes(CC.optimizer_lattice(interp), argtypes, inferred.nargs, inferred.isva)
return IRInterpretationState(interp, method_info, ir, mi, argtypes,
world, min_world, max_world)
end
Expand Down Expand Up @@ -974,34 +970,36 @@ function _abstract_eval_invoke_inst(interp::DAEInterpreter, inst::Union{CC.Instr
end

@override function CC.abstract_eval_statement_expr(interp::DAEInterpreter, inst::Expr, vtypes::Nothing, irsv::IRInterpretationState)
(; rt, exct, effects) = @invoke CC.abstract_eval_statement_expr(interp::AbstractInterpreter, inst::Expr, vtypes::Nothing, irsv::IRInterpretationState)

if (!interp.ipo_analysis_mode || interp.in_analysis) && !isa(rt, Const) && !isa(rt, Incidence) && !CC.isType(rt) && !is_all_inc_or_const(Any[rt])
argtypes = CC.collect_argtypes(interp, inst.args, nothing, irsv)
if argtypes === nothing
return CC.RTEffects(rt, exct, effects)
end
if is_all_inc_or_const(argtypes)
if inst.head in (:call, :invoke) && CC.hasintersect(widenconst(argtypes[inst.head === :call ? 1 : 2]), Union{typeof(variable), typeof(sim_time), typeof(state_ddt)})
# The `variable` and `state_ddt` intrinsics can source Incidence. For all other
# calls, if there's no incidence in the arguments, there cannot be any incidence
# in the result.
ret = @invoke CC.abstract_eval_statement_expr(interp::AbstractInterpreter, inst::Expr, vtypes::Nothing, irsv::IRInterpretationState)
return Future{CC.RTEffects}(ret, interp, irsv) do ret, interp, irsv
(; rt, exct, effects) = ret
if (!interp.ipo_analysis_mode || interp.in_analysis) && !isa(rt, Const) && !isa(rt, Incidence) && !CC.isType(rt) && !is_all_inc_or_const(Any[rt])
argtypes = CC.collect_argtypes(interp, inst.args, nothing, irsv)
if argtypes === nothing
return CC.RTEffects(rt, exct, effects)
end
fb_inci = _fallback_incidence(argtypes)
if fb_inci !== nothing
update_type(t::Type) = Incidence(t, fb_inci.row, fb_inci.eps)
update_type(t::Incidence) = t
update_type(t::Const) = t
update_type(t::CC.PartialTypeVar) = t
update_type(t::PartialStruct) = PartialStruct(t.typ, Any[Base.isvarargtype(f) ? f : update_type(f) for f in t.fields])
update_type(t::CC.Conditional) = CC.Conditional(t.slot, update_type(t.thentype), update_type(t.elsetype))
newrt = update_type(rt)
return CC.RTEffects(newrt, exct, effects)
if is_all_inc_or_const(argtypes)
if inst.head in (:call, :invoke) && CC.hasintersect(widenconst(argtypes[inst.head === :call ? 1 : 2]), Union{typeof(variable), typeof(sim_time), typeof(state_ddt)})
# The `variable` and `state_ddt` intrinsics can source Incidence. For all other
# calls, if there's no incidence in the arguments, there cannot be any incidence
# in the result.
return CC.RTEffects(rt, exct, effects)
end
fb_inci = _fallback_incidence(argtypes)
if fb_inci !== nothing
update_type(t::Type) = Incidence(t, fb_inci.row, fb_inci.eps)
update_type(t::Incidence) = t
update_type(t::Const) = t
update_type(t::CC.PartialTypeVar) = t
update_type(t::PartialStruct) = PartialStruct(t.typ, Any[Base.isvarargtype(f) ? f : update_type(f) for f in t.fields])
update_type(t::CC.Conditional) = CC.Conditional(t.slot, update_type(t.thentype), update_type(t.elsetype))
newrt = update_type(rt)
return CC.RTEffects(newrt, exct, effects)
end
end
end
return CC.RTEffects(rt, exct, effects)
end
return CC.RTEffects(rt, exct, effects)
end

@override function CC.compute_forwarded_argtypes(interp::DAEInterpreter, arginfo::ArgInfo, sv::AbsIntState)
Expand Down Expand Up @@ -1218,11 +1216,12 @@ function infer_ir!(ir, interp::AbstractInterpreter, mi::MethodInstance)
end
end

method_info = CC.MethodInfo(#=propagate_inbounds=#true, nothing)
(nargs, isva) = isa(mi.def, Method) ? (mi.def.nargs, mi.def.isva) : (0, false)
method_info = CC.SpecInfo(nargs, isva, #=propagate_inbounds=#true, nothing)
min_world = world = get_inference_world(interp)
max_world = get_world_counter()
irsv = IRInterpretationState(interp, method_info, ir, mi, ir.argtypes, world, min_world, max_world)
(rt, nothrow) = CC._ir_abstract_constant_propagation(interp, irsv)
(rt, nothrow) = CC.ir_abstract_constant_propagation(interp, irsv)
return rt
end

Expand Down
2 changes: 1 addition & 1 deletion src/transform/common.jl
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ function remap_info(remap_ir!, info)
if isa(result, CC.SemiConcreteResult)
let ir = copy(result.ir)
remap_ir!(ir)
CC.SemiConcreteResult(result.mi, ir, result.effects)
CC.SemiConcreteResult(result.mi, ir, result.effects, result.spec_info)
end
elseif isa(result, CC.ConstPropResult)
if isa(result.result.src, DAECache)
Expand Down
Loading