@@ -3918,29 +3918,38 @@ function invoke_NF(argexprs, etype::ANY, atypes, sv, atype_unlimited::ANY,
3918
3918
end
3919
3919
3920
3920
if nu > 1
3921
- spec_hit = nothing
3922
3921
spec_miss = nothing
3923
3922
error_label = nothing
3924
- linfo_var = add_slot! (sv. src, MethodInstance, false )
3925
3923
ex = Expr (:call )
3926
3924
ex. args = copy (argexprs)
3927
3925
ex. typ = etype
3928
3926
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
3930
3937
for i = length (atypes): - 1 : 1
3931
3938
if i == 1 && ! (invoke_texpr === nothing )
3932
3939
unshift! (stmts, invoke_texpr)
3933
- arg_hoisted = true
3934
3940
end
3935
3941
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
3944
3953
end
3945
3954
end
3946
3955
invoke_fexpr === nothing || unshift! (stmts, invoke_fexpr)
@@ -3951,9 +3960,11 @@ function invoke_NF(argexprs, etype::ANY, atypes, sv, atype_unlimited::ANY,
3951
3960
li === nothing && return false
3952
3961
add_backedge! (li, sv)
3953
3962
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
3957
3968
return stmt
3958
3969
else
3959
3970
local ti = atypes[i]
@@ -3991,30 +4002,18 @@ function invoke_NF(argexprs, etype::ANY, atypes, sv, atype_unlimited::ANY,
3991
4002
end
3992
4003
end
3993
4004
local match = splitunion (atypes, length (atypes))
3994
- if match != = false && spec_hit != = nothing
4005
+ if match != = false && spec_hit
3995
4006
append! (stmts, match)
3996
4007
if error_label != = nothing
3997
4008
push! (stmts, error_label)
3998
4009
push! (stmts, Expr (:call , GlobalRef (_topmod (sv. mod), :error ), " fatal error in type inference (type bound)" ))
3999
4010
end
4000
- local ret_var, merge
4001
4011
if spec_miss != = nothing
4002
- ret_var = add_slot! (sv. src, widenconst (ex. typ), false )
4003
- merge = genlabel (sv)
4004
4012
push! (stmts, spec_miss)
4005
4013
push! (stmts, Expr (:(= ), ret_var, ex))
4006
4014
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)
4017
4015
end
4016
+ push! (stmts, merge)
4018
4017
return (ret_var, stmts)
4019
4018
end
4020
4019
else
0 commit comments