Skip to content

Commit

Permalink
Merge branch 'master' into new-heuristics
Browse files Browse the repository at this point in the history
  • Loading branch information
gbaraldi committed Jul 20, 2023
2 parents 15b34a5 + 51941ed commit 9f3ca7c
Show file tree
Hide file tree
Showing 58 changed files with 668 additions and 269 deletions.
2 changes: 1 addition & 1 deletion HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ New language features
---------------------

* JuliaSyntax.jl is now used as the default parser, providing better diagnostics and faster
parsing. Set environment variable `JULIA_USE_NEW_PARSER` to `0` to switch back to the old
parsing. Set environment variable `JULIA_USE_FLISP_PARSER` to `1` to switch back to the old
parser if necessary (and if you find this necessary, please file an issue) ([#46372]).
* `` (U+297A, `\leftarrowsubset`) and `` (U+2977, `\leftarrowless`)
may now be used as binary operators with arrow precedence. ([#45962])
Expand Down
2 changes: 1 addition & 1 deletion base/Base.jl
Original file line number Diff line number Diff line change
Expand Up @@ -604,7 +604,7 @@ function __init__()
_require_world_age[] = get_world_counter()
# Prevent spawned Julia process from getting stuck waiting on Tracy to connect.
delete!(ENV, "JULIA_WAIT_FOR_TRACY")
if get_bool_env("JULIA_USE_NEW_PARSER", true) === true
if get_bool_env("JULIA_USE_FLISP_PARSER", false) === false
JuliaSyntax.enable_in_core!()
end
nothing
Expand Down
2 changes: 1 addition & 1 deletion base/compiler/abstractinterpretation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2053,7 +2053,7 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f),
end

function abstract_call_opaque_closure(interp::AbstractInterpreter,
closure::PartialOpaque, arginfo::ArgInfo, si::StmtInfo, sv::InferenceState, check::Bool=true)
closure::PartialOpaque, arginfo::ArgInfo, si::StmtInfo, sv::AbsIntState, check::Bool=true)
sig = argtypes_to_type(arginfo.argtypes)
result = abstract_call_method(interp, closure.source::Method, sig, Core.svec(), false, si, sv)
(; rt, edge, effects) = result
Expand Down
4 changes: 1 addition & 3 deletions base/compiler/abstractlattice.jl
Original file line number Diff line number Diff line change
Expand Up @@ -249,9 +249,7 @@ end
isa(x, Const) && return true
return is_forwardable_argtype(widenlattice(𝕃), x)
end
@nospecializeinfer function is_forwardable_argtype(::JLTypeLattice, @nospecialize x)
return false
end
@nospecializeinfer is_forwardable_argtype(::JLTypeLattice, @nospecialize x) = false

"""
widenreturn(𝕃ᵢ::AbstractLattice, @nospecialize(rt), info::BestguessInfo) -> new_bestguess
Expand Down
34 changes: 19 additions & 15 deletions base/compiler/inferenceresult.jl
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ function pick_const_args!(𝕃::AbstractLattice, cache_argtypes::Vector{Any}, ov
cache_argtype = cache_argtypes[i]
if !is_argtype_match(𝕃, given_argtype, cache_argtype, false)
# prefer the argtype we were given over the one computed from `linfo`
if (isa(given_argtype, PartialStruct) && isa(cache_argtype, Type) &&
!(𝕃, given_argtype, cache_argtype))
# if the type information of this `PartialStruct` is less strict than
# declared method signature, narrow it down using `tmeet`
given_argtype = tmeet(𝕃, given_argtype, cache_argtype)
end
cache_argtypes[i] = given_argtype
overridden_by_const[i] = true
end
Expand All @@ -80,7 +86,7 @@ end

va_process_argtypes(𝕃::AbstractLattice, given_argtypes::Vector{Any}, mi::MethodInstance) =
va_process_argtypes(Returns(nothing), 𝕃, given_argtypes, mi)
function va_process_argtypes(@nospecialize(va_handler!), 𝕃::AbstractLattice, given_argtypes::Vector{Any}, mi::MethodInstance)
function va_process_argtypes(@specialize(va_handler!), 𝕃::AbstractLattice, given_argtypes::Vector{Any}, mi::MethodInstance)
def = mi.def
isva = isa(def, Method) ? def.isva : false
nargs = isa(def, Method) ? Int(def.nargs) : length(mi.specTypes.parameters)
Expand Down Expand Up @@ -203,31 +209,29 @@ function elim_free_typevars(@nospecialize t)
end
end

function cache_lookup(lattice::AbstractLattice, linfo::MethodInstance, given_argtypes::Vector{Any}, cache::Vector{InferenceResult})
function cache_lookup(𝕃::AbstractLattice, linfo::MethodInstance, given_argtypes::Vector{Any}, cache::Vector{InferenceResult})
method = linfo.def::Method
nargs::Int = method.nargs
nargs = Int(method.nargs)
method.isva && (nargs -= 1)
length(given_argtypes) >= nargs || return nothing
length(given_argtypes) nargs || return nothing
for cached_result in cache
cached_result.linfo === linfo || continue
cache_match = true
cache_argtypes = cached_result.argtypes
cache_overridden_by_const = cached_result.overridden_by_const
for i in 1:nargs
if !is_argtype_match(lattice, widenmustalias(given_argtypes[i]),
cache_argtypes[i],
cache_overridden_by_const[i])
cache_match = false
break
if !is_argtype_match(𝕃, widenmustalias(given_argtypes[i]),
cache_argtypes[i], cache_overridden_by_const[i])
@goto next_cache
end
end
if method.isva && cache_match
cache_match = is_argtype_match(lattice, tuple_tfunc(lattice, given_argtypes[(nargs + 1):end]),
cache_argtypes[end],
cache_overridden_by_const[end])
if method.isva
if !is_argtype_match(𝕃, tuple_tfunc(𝕃, given_argtypes[(nargs + 1):end]),
cache_argtypes[end], cache_overridden_by_const[end])
@goto next_cache
end
end
cache_match || continue
return cached_result
@label next_cache
end
return nothing
end
5 changes: 3 additions & 2 deletions base/compiler/inferencestate.jl
Original file line number Diff line number Diff line change
Expand Up @@ -768,9 +768,10 @@ end
iterate(unw::AbsIntStackUnwind) = (unw.sv, (unw.sv, 0))
function iterate(unw::AbsIntStackUnwind, (sv, cyclei)::Tuple{AbsIntState, Int})
# iterate through the cycle before walking to the parent
if cyclei < length(callers_in_cycle(sv))
callers = callers_in_cycle(sv)
if callers !== () && cyclei < length(callers)
cyclei += 1
parent = callers_in_cycle(sv)[cyclei]
parent = callers[cyclei]
else
cyclei = 0
parent = frame_parent(sv)
Expand Down
108 changes: 54 additions & 54 deletions base/compiler/ssair/inlining.jl
Original file line number Diff line number Diff line change
Expand Up @@ -322,8 +322,7 @@ inline_node_is_duplicate(topline::LineInfoNode, line::LineInfoNode) =
topline.line === line.line

function ir_inline_linetable!(linetable::Vector{LineInfoNode}, inlinee_ir::IRCode,
inlinee::MethodInstance,
inlined_at::Int32)
inlinee::MethodInstance, inlined_at::Int32)
inlinee_def = inlinee.def::Method
coverage = coverage_enabled(inlinee_def.module)
linetable_offset::Int32 = length(linetable)
Expand Down Expand Up @@ -358,18 +357,18 @@ function ir_inline_linetable!(linetable::Vector{LineInfoNode}, inlinee_ir::IRCod
end

function ir_prepare_inlining!(insert_node!::Inserter, inline_target::Union{IRCode, IncrementalCompact},
linetable::Vector{LineInfoNode}, ir′::IRCode, sparam_vals::SimpleVector,
mi::MethodInstance, inlined_at::Int32, argexprs::Vector{Any})
ir::IRCode, mi::MethodInstance, inlined_at::Int32, argexprs::Vector{Any})
def = mi.def::Method
linetable = inline_target isa IRCode ? inline_target.linetable : inline_target.ir.linetable
topline::Int32 = length(linetable) + Int32(1)
linetable_offset, extra_coverage_line = ir_inline_linetable!(linetable, ir, mi, inlined_at)
linetable_offset, extra_coverage_line = ir_inline_linetable!(linetable, ir, mi, inlined_at)
if extra_coverage_line != 0
insert_node!(NewInstruction(Expr(:code_coverage_effect), Nothing, extra_coverage_line))
end
sp_ssa = nothing
if !validate_sparams(sparam_vals)
spvals_ssa = nothing
if !validate_sparams(mi.sparam_vals)
# N.B. This works on the caller-side argexprs, (i.e. before the va fixup below)
sp_ssa = insert_node!(
spvals_ssa = insert_node!(
effect_free_and_nothrow(NewInstruction(Expr(:call, Core._compute_sparams, def, argexprs...), SimpleVector, topline)))
end
if def.isva
Expand All @@ -382,20 +381,17 @@ function ir_prepare_inlining!(insert_node!::Inserter, inline_target::Union{IRCod
# Replace the first argument by a load of the capture environment
argexprs[1] = insert_node!(
NewInstruction(Expr(:call, GlobalRef(Core, :getfield), argexprs[1], QuoteNode(:captures)),
ir.argtypes[1], topline))
ir.argtypes[1], topline))
end
return (Pair{Union{Nothing, SSAValue}, Vector{Any}}(sp_ssa, argexprs), linetable_offset)
return SSASubstitute(mi, argexprs, spvals_ssa, linetable_offset)
end

function ir_inline_item!(compact::IncrementalCompact, idx::Int, argexprs::Vector{Any},
linetable::Vector{LineInfoNode}, item::InliningTodo,
boundscheck::Symbol, todo_bbs::Vector{Tuple{Int, Int}})
item::InliningTodo, boundscheck::Symbol, todo_bbs::Vector{Tuple{Int, Int}})
# Ok, do the inlining here
sparam_vals = item.mi.sparam_vals
inlined_at = compact.result[idx][:line]

((sp_ssa, argexprs), linetable_offset) = ir_prepare_inlining!(InsertHere(compact),
compact, linetable, item.ir, sparam_vals, item.mi, inlined_at, argexprs)
ssa_substitute = ir_prepare_inlining!(InsertHere(compact), compact, item.ir, item.mi, inlined_at, argexprs)

if boundscheck === :default || boundscheck === :propagate
if (compact.result[idx][:flag] & IR_FLAG_INBOUNDS) != 0
Expand All @@ -405,8 +401,6 @@ function ir_inline_item!(compact::IncrementalCompact, idx::Int, argexprs::Vector
# If the iterator already moved on to the next basic block,
# temporarily re-open in again.
local return_value
def = item.mi.def::Method
sig = def.sig
# Special case inlining that maintains the current basic block if there's only one BB in the target
new_new_offset = length(compact.new_new_nodes)
late_fixup_offset = length(compact.late_fixup)
Expand All @@ -418,7 +412,9 @@ function ir_inline_item!(compact::IncrementalCompact, idx::Int, argexprs::Vector
# face of rename_arguments! mutating in place - should figure out
# something better eventually.
inline_compact[idx′] = nothing
stmt′ = ssa_substitute!(InsertBefore(inline_compact, SSAValue(idx′)), inline_compact[SSAValue(idx′)], stmt′, argexprs, sig, sparam_vals, sp_ssa, linetable_offset, boundscheck)
insert_node! = InsertBefore(inline_compact, SSAValue(idx′))
stmt′ = ssa_substitute!(insert_node!, inline_compact[SSAValue(idx′)], stmt′,
ssa_substitute, boundscheck)
if isa(stmt′, ReturnNode)
val = stmt′.val
return_value = SSAValue(idx′)
Expand All @@ -445,7 +441,9 @@ function ir_inline_item!(compact::IncrementalCompact, idx::Int, argexprs::Vector
inline_compact = IncrementalCompact(compact, item.ir, compact.result_idx)
for ((_, idx′), stmt′) in inline_compact
inline_compact[idx′] = nothing
stmt′ = ssa_substitute!(InsertBefore(inline_compact, SSAValue(idx′)), inline_compact[SSAValue(idx′)], stmt′, argexprs, sig, sparam_vals, sp_ssa, linetable_offset, boundscheck)
insert_node! = InsertBefore(inline_compact, SSAValue(idx′))
stmt′ = ssa_substitute!(insert_node!, inline_compact[SSAValue(idx′)], stmt′,
ssa_substitute, boundscheck)
if isa(stmt′, ReturnNode)
if isdefined(stmt′, :val)
val = stmt′.val
Expand Down Expand Up @@ -554,11 +552,10 @@ excluding cases where `case.sig::UnionAll`.
In short, here we can process the dispatch candidates in order, assuming we haven't changed
their order somehow somewhere up to this point.
"""
function ir_inline_unionsplit!(compact::IncrementalCompact, idx::Int,
argexprs::Vector{Any}, linetable::Vector{LineInfoNode},
(; fully_covered, atype, cases, bbs)::UnionSplit,
boundscheck::Symbol, todo_bbs::Vector{Tuple{Int, Int}},
params::OptimizationParams)
function ir_inline_unionsplit!(compact::IncrementalCompact, idx::Int, argexprs::Vector{Any},
union_split::UnionSplit, boundscheck::Symbol,
todo_bbs::Vector{Tuple{Int,Int}}, params::OptimizationParams)
(; fully_covered, atype, cases, bbs) = union_split
stmt, typ, line = compact.result[idx][:inst], compact.result[idx][:type], compact.result[idx][:line]
join_bb = bbs[end]
pn = PhiNode()
Expand Down Expand Up @@ -606,7 +603,7 @@ function ir_inline_unionsplit!(compact::IncrementalCompact, idx::Int,
end
end
if isa(case, InliningTodo)
val = ir_inline_item!(compact, idx, argexprs′, linetable, case, boundscheck, todo_bbs)
val = ir_inline_item!(compact, idx, argexprs′, case, boundscheck, todo_bbs)
elseif isa(case, InvokeCase)
inst = Expr(:invoke, case.invoke, argexprs′...)
flag = flags_for_effects(case.effects)
Expand Down Expand Up @@ -698,9 +695,9 @@ function batch_inline!(ir::IRCode, todo::Vector{Pair{Int,Any}}, propagate_inboun
end
end
if isa(item, InliningTodo)
compact.ssa_rename[old_idx] = ir_inline_item!(compact, idx, argexprs, ir.linetable, item, boundscheck, state.todo_bbs)
compact.ssa_rename[old_idx] = ir_inline_item!(compact, idx, argexprs, item, boundscheck, state.todo_bbs)
elseif isa(item, UnionSplit)
compact.ssa_rename[old_idx] = ir_inline_unionsplit!(compact, idx, argexprs, ir.linetable, item, boundscheck, state.todo_bbs, params)
compact.ssa_rename[old_idx] = ir_inline_unionsplit!(compact, idx, argexprs, item, boundscheck, state.todo_bbs, params)
end
compact[idx] = nothing
refinish && finish_current_bb!(compact, 0)
Expand Down Expand Up @@ -1795,15 +1792,18 @@ function late_inline_special_case!(
return nothing
end

function ssa_substitute!(insert_node!::Inserter,
subst_inst::Instruction, @nospecialize(val), arg_replacements::Vector{Any},
@nospecialize(spsig), spvals::SimpleVector,
spvals_ssa::Union{Nothing, SSAValue},
linetable_offset::Int32, boundscheck::Symbol)
struct SSASubstitute
mi::MethodInstance
arg_replacements::Vector{Any}
spvals_ssa::Union{Nothing,SSAValue}
linetable_offset::Int32
end

function ssa_substitute!(insert_node!::Inserter, subst_inst::Instruction, @nospecialize(val),
ssa_substitute::SSASubstitute, boundscheck::Symbol)
subst_inst[:flag] &= ~IR_FLAG_INBOUNDS
subst_inst[:line] += linetable_offset
return ssa_substitute_op!(insert_node!, subst_inst,
val, arg_replacements, spsig, spvals, spvals_ssa, boundscheck)
subst_inst[:line] += ssa_substitute.linetable_offset
return ssa_substitute_op!(insert_node!, subst_inst, val, ssa_substitute, boundscheck)
end

function insert_spval!(insert_node!::Inserter, spvals_ssa::SSAValue, spidx::Int, do_isdefined::Bool)
Expand All @@ -1819,26 +1819,24 @@ function insert_spval!(insert_node!::Inserter, spvals_ssa::SSAValue, spidx::Int,
return (ret, tcheck_not)
end

function ssa_substitute_op!(insert_node!::Inserter, subst_inst::Instruction,
@nospecialize(val), arg_replacements::Vector{Any},
@nospecialize(spsig), spvals::SimpleVector,
spvals_ssa::Union{Nothing, SSAValue},
boundscheck::Symbol)
function ssa_substitute_op!(insert_node!::Inserter, subst_inst::Instruction, @nospecialize(val),
ssa_substitute::SSASubstitute, boundscheck::Symbol)
if isa(val, Argument)
return arg_replacements[val.n]
return ssa_substitute.arg_replacements[val.n]
end
if isa(val, Expr)
e = val::Expr
head = e.head
sparam_vals = ssa_substitute.mi.sparam_vals
if head === :static_parameter
spidx = e.args[1]::Int
val = spvals[spidx]
val = sparam_vals[spidx]
if !isa(val, TypeVar) && val !== Vararg
return quoted(val)
else
flag = subst_inst[:flag]
maybe_undef = (flag & IR_FLAG_NOTHROW) == 0 && isa(val, TypeVar)
(ret, tcheck_not) = insert_spval!(insert_node!, spvals_ssa::SSAValue, spidx, maybe_undef)
(ret, tcheck_not) = insert_spval!(insert_node!, ssa_substitute.spvals_ssa::SSAValue, spidx, maybe_undef)
if maybe_undef
insert_node!(
NewInstruction(Expr(:throw_undef_if_not, val.name, tcheck_not), Nothing))
Expand All @@ -1847,27 +1845,29 @@ function ssa_substitute_op!(insert_node!::Inserter, subst_inst::Instruction,
end
elseif head === :isdefined && isa(e.args[1], Expr) && e.args[1].head === :static_parameter
spidx = (e.args[1]::Expr).args[1]::Int
val = spvals[spidx]
val = sparam_vals[spidx]
if !isa(val, TypeVar)
return true
else
(_, tcheck_not) = insert_spval!(insert_node!, spvals_ssa::SSAValue, spidx, true)
(_, tcheck_not) = insert_spval!(insert_node!, ssa_substitute.spvals_ssa::SSAValue, spidx, true)
return tcheck_not
end
elseif head === :cfunction && spvals_ssa === nothing
@assert !isa(spsig, UnionAll) || !isempty(spvals)
e.args[3] = ccall(:jl_instantiate_type_in_env, Any, (Any, Any, Ptr{Any}), e.args[3], spsig, spvals)
elseif head === :cfunction && ssa_substitute.spvals_ssa === nothing
msig = (ssa_substitute.mi.def::Method).sig
@assert !isa(msig, UnionAll) || !isempty(sparam_vals)
e.args[3] = ccall(:jl_instantiate_type_in_env, Any, (Any, Any, Ptr{Any}), e.args[3], msig, sparam_vals)
e.args[4] = svec(Any[
ccall(:jl_instantiate_type_in_env, Any, (Any, Any, Ptr{Any}), argt, spsig, spvals)
ccall(:jl_instantiate_type_in_env, Any, (Any, Any, Ptr{Any}), argt, msig, sparam_vals)
for argt in e.args[4]::SimpleVector ]...)
elseif head === :foreigncall && spvals_ssa === nothing
@assert !isa(spsig, UnionAll) || !isempty(spvals)
elseif head === :foreigncall && ssa_substitute.spvals_ssa === nothing
msig = (ssa_substitute.mi.def::Method).sig
@assert !isa(msig, UnionAll) || !isempty(sparam_vals)
for i = 1:length(e.args)
if i == 2
e.args[2] = ccall(:jl_instantiate_type_in_env, Any, (Any, Any, Ptr{Any}), e.args[2], spsig, spvals)
e.args[2] = ccall(:jl_instantiate_type_in_env, Any, (Any, Any, Ptr{Any}), e.args[2], msig, sparam_vals)
elseif i == 3
e.args[3] = svec(Any[
ccall(:jl_instantiate_type_in_env, Any, (Any, Any, Ptr{Any}), argt, spsig, spvals)
ccall(:jl_instantiate_type_in_env, Any, (Any, Any, Ptr{Any}), argt, msig, sparam_vals)
for argt in e.args[3]::SimpleVector ]...)
end
end
Expand All @@ -1884,7 +1884,7 @@ function ssa_substitute_op!(insert_node!::Inserter, subst_inst::Instruction,
isa(val, Union{SSAValue, NewSSAValue}) && return val # avoid infinite loop
urs = userefs(val)
for op in urs
op[] = ssa_substitute_op!(insert_node!, subst_inst, op[], arg_replacements, spsig, spvals, spvals_ssa, boundscheck)
op[] = ssa_substitute_op!(insert_node!, subst_inst, op[], ssa_substitute, boundscheck)
end
return urs[]
end
Loading

0 comments on commit 9f3ca7c

Please sign in to comment.