Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

optimizer: support callsite annotations of @inline and @noinline #40754

Closed
wants to merge 17 commits into from
Closed
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Cleanup callsite noinline code, handle const-prop callsite noinline
  • Loading branch information
dghosef committed Jun 19, 2021
commit ff33482ff1db6ce57d31c08316514c2459b1f08d
47 changes: 21 additions & 26 deletions base/compiler/ssair/inlining.jl
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,7 @@ function rewrite_apply_exprargs!(ir::IRCode, todo::Vector{Pair{Int, Any}}, idx::
argexprs::Vector{Any}, atypes::Vector{Any}, arginfos::Vector{Any},
arg_start::Int, istate::InliningState)

flag = ir.stmts[idx][:flag]
new_argexprs = Any[argexprs[arg_start]]
new_atypes = Any[atypes[arg_start]]
# loop over original arguments and flatten any known iterators
Expand Down Expand Up @@ -655,8 +656,9 @@ function rewrite_apply_exprargs!(ir::IRCode, todo::Vector{Pair{Int, Any}}, idx::
info = call.info
handled = false
if isa(info, ConstCallInfo)
if maybe_handle_const_call!(ir, state1.id, new_stmt, info, new_sig,
call.rt, istate, false, todo)
if !is_stmt_noinline(flag) &&
maybe_handle_const_call!(ir, state1.id, new_stmt, info, new_sig,
call.rt, istate, false, todo)
handled = true
else
info = info.call
Expand All @@ -667,7 +669,7 @@ function rewrite_apply_exprargs!(ir::IRCode, todo::Vector{Pair{Int, Any}}, idx::
MethodMatchInfo[info] : info.matches
# See if we can inline this call to `iterate`
analyze_single_call!(ir, todo, state1.id, new_stmt,
new_sig, call.rt, info, istate)
new_sig, call.rt, info, istate, flag)
end
if i != length(thisarginfo.each)
valT = getfield_tfunc(call.rt, Const(1))
Expand Down Expand Up @@ -790,7 +792,7 @@ function validate_sparams(sparams::SimpleVector)
end

function analyze_method!(match::MethodMatch, atypes::Vector{Any},
state::InliningState, @nospecialize(stmttyp), dont_inline::Bool)
state::InliningState, @nospecialize(stmttyp), flag::UInt8)
method = match.method
methsig = method.sig

Expand All @@ -810,7 +812,7 @@ function analyze_method!(match::MethodMatch, atypes::Vector{Any},
validate_sparams(match.sparams) || return nothing


if !state.params.inlining || dont_inline
if !state.params.inlining || is_stmt_noinline(flag)
return compileable_specialization(state.et, match)
end

Expand Down Expand Up @@ -1049,20 +1051,10 @@ is_builtin(s::Signature) =
isa(s.f, Builtin) ||
s.ft ⊑ Builtin

function check_noinline_flag(ir::IRCode, idx::Int)
try
(ir.stmts[idx][:flag] & IR_FLAG_NOINLINE) != 0
catch BoundsError
false
end

end

function inline_invoke!(ir::IRCode, idx::Int, sig::Signature, info::InvokeCallInfo,
state::InliningState, todo::Vector{Pair{Int, Any}})
state::InliningState, todo::Vector{Pair{Int, Any}}, flag::UInt8)
stmt = ir.stmts[idx][:inst]
calltype = ir.stmts[idx][:type]
dont_inline = check_noinline_flag(ir, idx)

if !info.match.fully_covers
# TODO: We could union split out the signature check and continue on
Expand All @@ -1074,7 +1066,7 @@ function inline_invoke!(ir::IRCode, idx::Int, sig::Signature, info::InvokeCallIn
atypes = atypes[4:end]
pushfirst!(atypes, atype0)

result = analyze_method!(info.match, atypes, state, calltype, dont_inline)
result = analyze_method!(info.match, atypes, state, calltype, flag)
handle_single_case!(ir, stmt, idx, result, true, todo)
return nothing
end
Expand Down Expand Up @@ -1169,12 +1161,11 @@ end

function analyze_single_call!(ir::IRCode, todo::Vector{Pair{Int, Any}}, idx::Int, @nospecialize(stmt),
sig::Signature, @nospecialize(calltype), infos::Vector{MethodMatchInfo},
state::InliningState)
state::InliningState, flag::UInt8)
cases = Pair{Any, Any}[]
signature_union = Union{}
only_method = nothing # keep track of whether there is one matching method
too_many = false
dont_inline = check_noinline_flag(ir, idx)
local meth
local fully_covered = true
for i in 1:length(infos)
Expand Down Expand Up @@ -1203,7 +1194,7 @@ function analyze_single_call!(ir::IRCode, todo::Vector{Pair{Int, Any}}, idx::Int
fully_covered = false
continue
end
case = analyze_method!(match, sig.atypes, state, calltype, dont_inline)
case = analyze_method!(match, sig.atypes, state, calltype, flag)
if case === nothing
fully_covered = false
continue
Expand All @@ -1230,7 +1221,7 @@ function analyze_single_call!(ir::IRCode, todo::Vector{Pair{Int, Any}}, idx::Int
match = meth[1]
end
fully_covered = true
case = analyze_method!(match, sig.atypes, state, calltype, dont_inline)
case = analyze_method!(match, sig.atypes, state, calltype, flag)
case === nothing && return
push!(cases, Pair{Any,Any}(match.spec_types, case))
end
Expand Down Expand Up @@ -1280,6 +1271,8 @@ function maybe_handle_const_call!(ir::IRCode, idx::Int, stmt::Expr,
end
end

is_stmt_noinline(stmt_flag::UInt8) = stmt_flag & IR_FLAG_NOINLINE != 0

function assemble_inline_todo!(ir::IRCode, state::InliningState)
# todo = (inline_idx, (isva, isinvoke, na), method, spvals, inline_linetable, inline_ir, lie)
todo = Pair{Int, Any}[]
Expand All @@ -1291,7 +1284,6 @@ function assemble_inline_todo!(ir::IRCode, state::InliningState)
stmt = ir.stmts[idx][:inst]
calltype = ir.stmts[idx][:type]
info = ir.stmts[idx][:info]
dont_inline = check_noinline_flag(ir, idx)

# Check whether this call was @pure and evaluates to a constant
if info isa MethodResultPure
Expand All @@ -1303,6 +1295,8 @@ function assemble_inline_todo!(ir::IRCode, state::InliningState)
info = info.info
end

flag = ir.stmts[idx][:flag]

# Inference determined this couldn't be analyzed. Don't question it.
if info === false
continue
Expand All @@ -1312,23 +1306,24 @@ function assemble_inline_todo!(ir::IRCode, state::InliningState)
# it'll have performed a specialized analysis for just this case. Use its
# result.
if isa(info, ConstCallInfo)
if maybe_handle_const_call!(ir, idx, stmt, info, sig, calltype, state, sig.f === Core.invoke, todo)
if !is_stmt_noinline(flag) &&
maybe_handle_const_call!(ir, idx, stmt, info, sig, calltype, state, sig.f === Core.invoke, todo)
continue
else
info = info.call
end
end

if isa(info, OpaqueClosureCallInfo)
result = analyze_method!(info.match, sig.atypes, state, calltype, dont_inline)
result = analyze_method!(info.match, sig.atypes, state, calltype, flag)
handle_single_case!(ir, stmt, idx, result, false, todo)
continue
end

# Handle invoke
if sig.f === Core.invoke
if isa(info, InvokeCallInfo)
inline_invoke!(ir, idx, sig, info, state, todo)
inline_invoke!(ir, idx, sig, info, state, todo, flag)
end
continue
end
Expand All @@ -1342,7 +1337,7 @@ function assemble_inline_todo!(ir::IRCode, state::InliningState)
continue
end

analyze_single_call!(ir, todo, idx, stmt, sig, calltype, infos, state)
analyze_single_call!(ir, todo, idx, stmt, sig, calltype, infos, state, flag)
end
todo
end
Expand Down