Skip to content

Commit

Permalink
Merge branch 'master' into jn/45759-46557-31485
Browse files Browse the repository at this point in the history
  • Loading branch information
vtjnash authored Aug 10, 2023
2 parents 7ef53af + 517ad06 commit 7afc7de
Show file tree
Hide file tree
Showing 142 changed files with 3,135 additions and 2,306 deletions.
2 changes: 1 addition & 1 deletion Make.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1503,7 +1503,7 @@ endef
WINE ?= wine

ifeq ($(BINARY),32)
HEAPLIM := --heap-size-hint=500M
HEAPLIM := --heap-size-hint=1000M
else
HEAPLIM :=
endif
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ and then use the command prompt to change into the resulting julia directory. By
Julia. However, most users should use the [most recent stable version](https://github.com/JuliaLang/julia/releases)
of Julia. You can get this version by running:

git checkout v1.9.0
git checkout v1.9.2

To build the `julia` executable, run `make` from within the julia directory.

Expand Down
2 changes: 1 addition & 1 deletion base/binaryplatforms.jl
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,7 @@ julia> wordsize(Platform("x86_64", "macos"))
wordsize(p::AbstractPlatform) = (arch(p) ("i686", "armv6l", "armv7l")) ? 32 : 64

"""
triplet(p::AbstractPlatform; exclude_tags::Vector{String})
triplet(p::AbstractPlatform)
Get the target triplet for the given `Platform` object as a `String`.
Expand Down
10 changes: 6 additions & 4 deletions base/bitarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1791,9 +1791,10 @@ function bit_map!(f::F, dest::BitArray, A::BitArray) where F
dest_last = destc[len_Ac]
_msk = _msk_end(A)
# first zero out the bits mask is going to change
destc[len_Ac] = (dest_last & (~_msk))
# then update bits by `or`ing with a masked RHS
destc[len_Ac] |= f(Ac[len_Ac]) & _msk
# DO NOT SEPARATE ONTO TO LINES.
# Otherwise there will be bugs when Ac aliases destc
destc[len_Ac] = (dest_last & (~_msk)) | f(Ac[len_Ac]) & _msk
dest
end
function bit_map!(f::F, dest::BitArray, A::BitArray, B::BitArray) where F
Expand All @@ -1812,9 +1813,10 @@ function bit_map!(f::F, dest::BitArray, A::BitArray, B::BitArray) where F
dest_last = destc[len_Ac]
_msk = _msk_end(min_bitlen)
# first zero out the bits mask is going to change
destc[len_Ac] = (dest_last & ~(_msk))
# then update bits by `or`ing with a masked RHS
destc[len_Ac] |= f(Ac[end], Bc[end]) & _msk
# DO NOT SEPARATE ONTO TO LINES.
# Otherwise there will be bugs when Ac or Bc aliases destc
destc[len_Ac] = (dest_last & ~(_msk)) | f(Ac[end], Bc[end]) & _msk
dest
end

Expand Down
16 changes: 8 additions & 8 deletions base/client.jl
Original file line number Diff line number Diff line change
Expand Up @@ -325,11 +325,11 @@ function exec_options(opts)
end
end
if repl || is_interactive::Bool
if interactiveinput
banner = (opts.banner != 0) # --banner!=no
else
banner = (opts.banner == 1) # --banner=yes
end
b = opts.banner
auto = b == -1
banner = b == 0 || (auto && !interactiveinput) ? :no :
b == 1 || (auto && interactiveinput) ? :yes :
:short # b == 2
run_main_repl(interactiveinput, quiet, banner, history_file, color_set)
end
nothing
Expand Down Expand Up @@ -409,14 +409,14 @@ end
global active_repl

# run the requested sort of evaluation loop on stdio
function run_main_repl(interactive::Bool, quiet::Bool, banner::Bool, history_file::Bool, color_set::Bool)
function run_main_repl(interactive::Bool, quiet::Bool, banner::Symbol, history_file::Bool, color_set::Bool)
load_InteractiveUtils()

if interactive && isassigned(REPL_MODULE_REF)
invokelatest(REPL_MODULE_REF[]) do REPL
term_env = get(ENV, "TERM", @static Sys.iswindows() ? "" : "dumb")
term = REPL.Terminals.TTYTerminal(term_env, stdin, stdout, stderr)
banner && Base.banner(term)
banner == :no || Base.banner(term, short=banner==:short)
if term.term_type == "dumb"
repl = REPL.BasicREPL(term)
quiet || @warn "Terminal not fully functional"
Expand All @@ -436,7 +436,7 @@ function run_main_repl(interactive::Bool, quiet::Bool, banner::Bool, history_fil
if interactive && !quiet
@warn "REPL provider not available: using basic fallback"
end
banner && Base.banner()
banner == :no || Base.banner(short=banner==:short)
let input = stdin
if isa(input, File) || isa(input, IOStream)
# for files, we can slurp in the whole thing at once
Expand Down
52 changes: 36 additions & 16 deletions base/compiler/abstractinterpretation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -773,11 +773,13 @@ struct ConstCallResults
const_result::ConstResult
effects::Effects
edge::MethodInstance
ConstCallResults(@nospecialize(rt),
const_result::ConstResult,
effects::Effects,
edge::MethodInstance) =
new(rt, const_result, effects, edge)
function ConstCallResults(
@nospecialize(rt),
const_result::ConstResult,
effects::Effects,
edge::MethodInstance)
return new(rt, const_result, effects, edge)
end
end

function abstract_call_method_with_const_args(interp::AbstractInterpreter,
Expand All @@ -791,24 +793,33 @@ function abstract_call_method_with_const_args(interp::AbstractInterpreter,
return nothing
end
eligibility = concrete_eval_eligible(interp, f, result, arginfo, sv)
concrete_eval_result = nothing
if eligibility === :concrete_eval
return concrete_eval_call(interp, f, result, arginfo, sv; invokecall)
concrete_eval_result = concrete_eval_call(interp, f, result, arginfo, sv, invokecall)
# if we don't inline the result of this concrete evaluation,
# give const-prop' a chance to inline a better method body
if !may_optimize(interp) || (
may_inline_concrete_result(concrete_eval_result.const_result::ConcreteResult) ||
concrete_eval_result.rt === Bottom) # unless this call deterministically throws and thus is non-inlineable
return concrete_eval_result
end
# TODO allow semi-concrete interp for this call?
end
mi = maybe_get_const_prop_profitable(interp, result, f, arginfo, si, match, sv)
mi === nothing && return nothing
mi === nothing && return concrete_eval_result
if is_constprop_recursed(result, mi, sv)
add_remark!(interp, sv, "[constprop] Edge cycle encountered")
return nothing
end
# try semi-concrete evaluation
if eligibility === :semi_concrete_eval
res = semi_concrete_eval_call(interp, mi, result, arginfo, sv)
if res !== nothing
return res
irinterp_result = semi_concrete_eval_call(interp, mi, result, arginfo, sv)
if irinterp_result !== nothing
return irinterp_result
end
end
# try constant prop'
return const_prop_call(interp, mi, result, arginfo, sv)
return const_prop_call(interp, mi, result, arginfo, sv, concrete_eval_result)
end

function const_prop_enabled(interp::AbstractInterpreter, sv::AbsIntState, match::MethodMatch)
Expand Down Expand Up @@ -887,7 +898,7 @@ function collect_const_args(argtypes::Vector{Any}, start::Int)
end

function concrete_eval_call(interp::AbstractInterpreter,
@nospecialize(f), result::MethodCallResult, arginfo::ArgInfo, sv::AbsIntState;
@nospecialize(f), result::MethodCallResult, arginfo::ArgInfo, sv::AbsIntState,
invokecall::Union{InvokeCall,Nothing}=nothing)
args = collect_const_args(arginfo, #=start=#2)
if invokecall !== nothing
Expand All @@ -901,7 +912,7 @@ function concrete_eval_call(interp::AbstractInterpreter,
Core._call_in_world_total(world, f, args...)
catch
# The evaluation threw. By :consistent-cy, we're guaranteed this would have happened at runtime
return ConstCallResults(Union{}, ConcreteResult(edge, result.effects), result.effects, edge)
return ConstCallResults(Bottom, ConcreteResult(edge, result.effects), result.effects, edge)
end
return ConstCallResults(Const(value), ConcreteResult(edge, EFFECTS_TOTAL, value), EFFECTS_TOTAL, edge)
end
Expand Down Expand Up @@ -1159,16 +1170,20 @@ function semi_concrete_eval_call(interp::AbstractInterpreter,
# that are newly resovled by irinterp
# state = InliningState(interp)
# ir = ssa_inlining_pass!(irsv.ir, state, propagate_inbounds(irsv))
new_effects = Effects(result.effects; nothrow)
return ConstCallResults(rt, SemiConcreteResult(mi, ir, new_effects), new_effects, mi)
effects = result.effects
if !is_nothrow(effects)
effects = Effects(effects; nothrow)
end
return ConstCallResults(rt, SemiConcreteResult(mi, ir, effects), effects, mi)
end
end
end
return nothing
end

function const_prop_call(interp::AbstractInterpreter,
mi::MethodInstance, result::MethodCallResult, arginfo::ArgInfo, sv::AbsIntState)
mi::MethodInstance, result::MethodCallResult, arginfo::ArgInfo, sv::AbsIntState,
concrete_eval_result::Union{Nothing,ConstCallResults}=nothing)
inf_cache = get_inference_cache(interp)
𝕃ᵢ = typeinf_lattice(interp)
inf_result = cache_lookup(𝕃ᵢ, mi, arginfo.argtypes, inf_cache)
Expand All @@ -1191,6 +1206,11 @@ function const_prop_call(interp::AbstractInterpreter,
return nothing
end
@assert inf_result.result !== nothing
if concrete_eval_result !== nothing
# override return type and effects with concrete evaluation result if available
inf_result.result = concrete_eval_result.rt
inf_result.ipo_effects = concrete_eval_result.effects
end
else
# found the cache for this constant prop'
if inf_result.result === nothing
Expand Down
6 changes: 3 additions & 3 deletions base/compiler/optimize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -618,7 +618,7 @@ function slot2reg(ir::IRCode, ci::CodeInfo, sv::OptimizationState)
svdef = sv.linfo.def
nargs = isa(svdef, Method) ? Int(svdef.nargs) : 0
@timeit "domtree 1" domtree = construct_domtree(ir.cfg.blocks)
defuse_insts = scan_slot_def_use(nargs, ci, ir.stmts.inst)
defuse_insts = scan_slot_def_use(nargs, ci, ir.stmts.stmt)
𝕃ₒ = optimizer_lattice(sv.inlining.interp)
@timeit "construct_ssa" ir = construct_ssa!(ci, ir, domtree, defuse_insts, sv.slottypes, 𝕃ₒ) # consumes `ir`
# NOTE now we have converted `ir` to the SSA form and eliminated slots
Expand Down Expand Up @@ -646,7 +646,7 @@ function statement_cost(ex::Expr, line::Int, src::Union{CodeInfo, IRCode}, sptyp
if ftyp === IntrinsicFunction && farg isa SSAValue
# if this comes from code that was already inlined into another function,
# Consts have been widened. try to recover in simple cases.
farg = isa(src, CodeInfo) ? src.code[farg.id] : src.stmts[farg.id][:inst]
farg = isa(src, CodeInfo) ? src.code[farg.id] : src[farg][:stmt]
if isa(farg, GlobalRef) || isa(farg, QuoteNode) || isa(farg, IntrinsicFunction) || isexpr(farg, :static_parameter)
ftyp = argextype(farg, src, sptypes)
end
Expand Down Expand Up @@ -741,7 +741,7 @@ function inline_cost(ir::IRCode, params::OptimizationParams,
cost_threshold::Integer=params.inline_cost_threshold)::InlineCostType
bodycost::Int = 0
for line = 1:length(ir.stmts)
stmt = ir.stmts[line][:inst]
stmt = ir[SSAValue(line)][:stmt]
thiscost = statement_or_branch_cost(stmt, line, ir, ir.sptypes, params)
bodycost = plus_saturate(bodycost, thiscost)
bodycost > cost_threshold && return MAX_INLINE_COST
Expand Down
4 changes: 2 additions & 2 deletions base/compiler/ssair/EscapeAnalysis/EscapeAnalysis.jl
Original file line number Diff line number Diff line change
Expand Up @@ -671,7 +671,7 @@ function analyze_escapes(ir::IRCode, nargs::Int, call_resolved::Bool, get_escape
local anyupdate = false

for pc in nstmts:-1:1
stmt = getinst(ir, pc)[:inst]
stmt = getinst(ir, pc)[:stmt]

# collect escape information
if isa(stmt, Expr)
Expand Down Expand Up @@ -784,7 +784,7 @@ function compute_frameinfo(ir::IRCode, call_resolved::Bool)
end
for idx in 1:nstmts+nnewnodes
inst = getinst(ir, idx)
stmt = inst[:inst]
stmt = inst[:stmt]
if !call_resolved
# TODO don't call `check_effect_free!` in the inlinear
check_effect_free!(ir, idx, stmt, inst[:type], 𝕃ₒ)
Expand Down
33 changes: 17 additions & 16 deletions base/compiler/ssair/inlining.jl
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ function cfg_inline_item!(ir::IRCode, idx::Int, todo::InliningTodo, state::CFGIn
last_block_idx = last(state.cfg.blocks[block].stmts)
if false # TODO: ((idx+1) == last_block_idx && isa(ir[SSAValue(last_block_idx)], GotoNode))
need_split = false
post_bb_id = -ir[SSAValue(last_block_idx)][:inst].label
post_bb_id = -ir[SSAValue(last_block_idx)][:stmt].label
else
post_bb_id = length(state.new_cfg_blocks) + length(inlinee_cfg.blocks) + (need_split_before ? 1 : 0)
need_split = true #!(idx == last_block_idx)
Expand Down Expand Up @@ -196,7 +196,7 @@ function cfg_inline_item!(ir::IRCode, idx::Int, todo::InliningTodo, state::CFGIn
for (old_block, new_block) in enumerate(bb_rename_range)
if (length(state.new_cfg_blocks[new_block].succs) == 0)
terminator_idx = last(inlinee_cfg.blocks[old_block].stmts)
terminator = todo.ir[SSAValue(terminator_idx)][:inst]
terminator = todo.ir[SSAValue(terminator_idx)][:stmt]
if isa(terminator, ReturnNode) && isdefined(terminator, :val)
any_edges = true
push!(state.new_cfg_blocks[new_block].succs, post_bb_id)
Expand Down Expand Up @@ -556,7 +556,7 @@ function ir_inline_unionsplit!(compact::IncrementalCompact, idx::Int, argexprs::
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]
stmt, typ, line = compact.result[idx][:stmt], compact.result[idx][:type], compact.result[idx][:line]
join_bb = bbs[end]
pn = PhiNode()
local bb = compact.active_result_bb
Expand Down Expand Up @@ -605,9 +605,9 @@ function ir_inline_unionsplit!(compact::IncrementalCompact, idx::Int, argexprs::
if isa(case, InliningTodo)
val = ir_inline_item!(compact, idx, argexprs′, case, boundscheck, todo_bbs)
elseif isa(case, InvokeCase)
inst = Expr(:invoke, case.invoke, argexprs′...)
invoke_stmt = Expr(:invoke, case.invoke, argexprs′...)
flag = flags_for_effects(case.effects)
val = insert_node_here!(compact, NewInstruction(inst, typ, case.info, line, flag))
val = insert_node_here!(compact, NewInstruction(invoke_stmt, typ, case.info, line, flag))
else
case = case::ConstantCase
val = case.val
Expand Down Expand Up @@ -993,7 +993,7 @@ function handle_single_case!(todo::Vector{Pair{Int,Any}},
ir::IRCode, idx::Int, stmt::Expr, @nospecialize(case),
isinvoke::Bool = false)
if isa(case, ConstantCase)
ir[SSAValue(idx)][:inst] = case.val
ir[SSAValue(idx)][:stmt] = case.val
elseif isa(case, InvokeCase)
is_foldable_nothrow(case.effects) && inline_const_if_inlineable!(ir[SSAValue(idx)]) && return nothing
isinvoke && rewrite_invoke_exprargs!(stmt)
Expand Down Expand Up @@ -1120,7 +1120,7 @@ function inline_apply!(todo::Vector{Pair{Int,Any}},
break
end
if nonempty_idx != 0
ir.stmts[idx][:inst] = stmt.args[nonempty_idx]
ir[SSAValue(idx)][:stmt] = stmt.args[nonempty_idx]
return nothing
end
end
Expand Down Expand Up @@ -1236,8 +1236,9 @@ end
# this method does not access the method table or otherwise process generic
# functions.
function process_simple!(todo::Vector{Pair{Int,Any}}, ir::IRCode, idx::Int, state::InliningState)
stmt = ir.stmts[idx][:inst]
rt = ir.stmts[idx][:type]
inst = ir[SSAValue(idx)]
stmt = inst[:stmt]
rt = inst[:type]
if !(stmt isa Expr)
check_effect_free!(ir, idx, stmt, rt, state)
return nothing
Expand All @@ -1247,7 +1248,7 @@ function process_simple!(todo::Vector{Pair{Int,Any}}, ir::IRCode, idx::Int, stat
if head === :splatnew
inline_splatnew!(ir, idx, stmt, rt, state)
elseif head === :new_opaque_closure
narrow_opaque_closure!(ir, stmt, ir.stmts[idx][:info], state)
narrow_opaque_closure!(ir, stmt, inst[:info], state)
elseif head === :invoke
sig = call_sig(ir, stmt)
sig === nothing && return nothing
Expand All @@ -1267,14 +1268,14 @@ function process_simple!(todo::Vector{Pair{Int,Any}}, ir::IRCode, idx::Int, stat
# Check if we match any of the early inliners
earlyres = early_inline_special_case(ir, stmt, rt, sig, state)
if isa(earlyres, SomeCase)
ir.stmts[idx][:inst] = earlyres.val
inst[:stmt] = earlyres.val
return nothing
end

if check_effect_free!(ir, idx, stmt, rt, state)
if sig.f === typeassert || (optimizer_lattice(state.interp), sig.ft, typeof(typeassert))
# typeassert is a no-op if effect free
ir.stmts[idx][:inst] = stmt.args[2]
inst[:stmt] = stmt.args[2]
return nothing
end
end
Expand All @@ -1288,7 +1289,7 @@ function process_simple!(todo::Vector{Pair{Int,Any}}, ir::IRCode, idx::Int, stat
# Special case inliners for regular functions
lateres = late_inline_special_case!(ir, idx, stmt, rt, sig, state)
if isa(lateres, SomeCase)
ir[SSAValue(idx)][:inst] = lateres.val
inst[:stmt] = lateres.val
check_effect_free!(ir, idx, lateres.val, rt, state)
return nothing
end
Expand Down Expand Up @@ -1576,7 +1577,7 @@ function handle_modifyfield!_call!(ir::IRCode, idx::Int, stmt::Expr, info::Modif
case === nothing && return nothing
stmt.head = :invoke_modify
pushfirst!(stmt.args, case.invoke)
ir.stmts[idx][:inst] = stmt
ir[SSAValue(idx)][:stmt] = stmt
return nothing
end

Expand Down Expand Up @@ -1636,7 +1637,7 @@ end
function inline_const_if_inlineable!(inst::Instruction)
rt = inst[:type]
if rt isa Const && is_inlineable_constant(rt.val)
inst[:inst] = quoted(rt.val)
inst[:stmt] = quoted(rt.val)
return true
end
inst[:flag] |= IR_FLAG_EFFECT_FREE | IR_FLAG_NOTHROW
Expand Down Expand Up @@ -1691,7 +1692,7 @@ end

function linear_inline_eligible(ir::IRCode)
length(ir.cfg.blocks) == 1 || return false
terminator = ir[SSAValue(last(ir.cfg.blocks[1].stmts))][:inst]
terminator = ir[SSAValue(last(ir.cfg.blocks[1].stmts))][:stmt]
isa(terminator, ReturnNode) || return false
isdefined(terminator, :val) || return false
return true
Expand Down
Loading

0 comments on commit 7afc7de

Please sign in to comment.