Skip to content

Commit a42a8c3

Browse files
committed
duplicate invoke expr during call method splitting
With the new gc-rooting pass, this should generate better code over the copying of just the method instance.
1 parent ce3c1ef commit a42a8c3

File tree

1 file changed

+28
-29
lines changed

1 file changed

+28
-29
lines changed

base/inference.jl

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3918,29 +3918,38 @@ function invoke_NF(argexprs, etype::ANY, atypes, sv, atype_unlimited::ANY,
39183918
end
39193919

39203920
if nu > 1
3921-
spec_hit = nothing
39223921
spec_miss = nothing
39233922
error_label = nothing
3924-
linfo_var = add_slot!(sv.src, MethodInstance, false)
39253923
ex = Expr(:call)
39263924
ex.args = copy(argexprs)
39273925
ex.typ = etype
39283926
stmts = []
3929-
arg_hoisted = false
3927+
3928+
local ret_var, merge, invoke_ex, spec_hit
3929+
ret_var = add_slot!(sv.src, widenconst(etype), false)
3930+
merge = genlabel(sv)
3931+
invoke_ex = copy(ex)
3932+
invoke_ex.head = :invoke
3933+
unshift!(invoke_ex.args, nothing)
3934+
spec_hit = false
3935+
3936+
# linearize the IR by moving the arguments to SSA position
39303937
for i = length(atypes):-1:1
39313938
if i == 1 && !(invoke_texpr === nothing)
39323939
unshift!(stmts, invoke_texpr)
3933-
arg_hoisted = true
39343940
end
39353941
ti = atypes[i]
3936-
if arg_hoisted || isa(ti, Union)
3937-
aei = ex.args[i]
3938-
if !effect_free(aei, sv.src, sv.mod, false)
3939-
arg_hoisted = true
3940-
newvar = newvar!(sv, ti)
3941-
unshift!(stmts, :($newvar = $aei))
3942-
ex.args[i] = newvar
3943-
end
3942+
aei = ex.args[i]
3943+
if !isa(aei, Slot) &&
3944+
!isa(aei, SSAValue) &&
3945+
!isa(aei, Symbol) &&
3946+
!isa(aei, QuoteNode) &&
3947+
!isa(aei, Int) &&
3948+
!isa(aei, Type) &&
3949+
!isa(aei, GlobalRef)
3950+
newvar = newvar!(sv, ti)
3951+
unshift!(stmts, :($newvar = $aei))
3952+
ex.args[i] = newvar
39443953
end
39453954
end
39463955
invoke_fexpr === nothing || unshift!(stmts, invoke_fexpr)
@@ -3951,9 +3960,11 @@ function invoke_NF(argexprs, etype::ANY, atypes, sv, atype_unlimited::ANY,
39513960
li === nothing && return false
39523961
add_backedge!(li, sv)
39533962
local stmt = []
3954-
push!(stmt, Expr(:(=), linfo_var, li))
3955-
spec_hit === nothing && (spec_hit = genlabel(sv))
3956-
push!(stmt, GotoNode(spec_hit.label))
3963+
invoke_ex = copy(invoke_ex)
3964+
invoke_ex.args[1] = li
3965+
push!(stmt, Expr(:(=), ret_var, invoke_ex))
3966+
push!(stmt, GotoNode(merge.label))
3967+
spec_hit = true
39573968
return stmt
39583969
else
39593970
local ti = atypes[i]
@@ -3991,30 +4002,18 @@ function invoke_NF(argexprs, etype::ANY, atypes, sv, atype_unlimited::ANY,
39914002
end
39924003
end
39934004
local match = splitunion(atypes, length(atypes))
3994-
if match !== false && spec_hit !== nothing
4005+
if match !== false && spec_hit
39954006
append!(stmts, match)
39964007
if error_label !== nothing
39974008
push!(stmts, error_label)
39984009
push!(stmts, Expr(:call, GlobalRef(_topmod(sv.mod), :error), "fatal error in type inference (type bound)"))
39994010
end
4000-
local ret_var, merge
40014011
if spec_miss !== nothing
4002-
ret_var = add_slot!(sv.src, widenconst(ex.typ), false)
4003-
merge = genlabel(sv)
40044012
push!(stmts, spec_miss)
40054013
push!(stmts, Expr(:(=), ret_var, ex))
40064014
push!(stmts, GotoNode(merge.label))
4007-
else
4008-
ret_var = newvar!(sv, ex.typ)
4009-
end
4010-
push!(stmts, spec_hit)
4011-
ex = copy(ex)
4012-
ex.head = :invoke
4013-
unshift!(ex.args, linfo_var)
4014-
push!(stmts, Expr(:(=), ret_var, ex))
4015-
if spec_miss !== nothing
4016-
push!(stmts, merge)
40174015
end
4016+
push!(stmts, merge)
40184017
return (ret_var, stmts)
40194018
end
40204019
else

0 commit comments

Comments
 (0)