@@ -190,8 +190,8 @@ function optimize(me::InferenceState)
190
190
# only care about certain errors (e.g. method errors and type errors).
191
191
if length (me. src. code) < 10
192
192
proven_pure = true
193
- for stmt in me. src. code
194
- if ! statement_effect_free (stmt , me)
193
+ for i in 1 : length ( me. src. code)
194
+ if ! statement_effect_free (me . src . code[i] , me, me . src . ssavaluetypes[i] )
195
195
proven_pure = false
196
196
break
197
197
end
359
359
function annotate_slot_load! (e:: Expr , vtypes:: VarTable , sv:: InferenceState , undefs:: Array{Bool,1} )
360
360
head = e. head
361
361
i0 = 1
362
- e. typ = maybe_widen_conditional (e. typ)
363
362
if is_meta_expr_head (head) || head === :const
364
363
return
365
364
end
@@ -406,13 +405,7 @@ function record_slot_assign!(sv::InferenceState)
406
405
lhs = expr. args[1 ]
407
406
rhs = expr. args[2 ]
408
407
if isa (lhs, Slot)
409
- if isa (rhs, Slot)
410
- # exprtype isn't yet computed for slots
411
- vt = st_i[slot_id (rhs)]. typ
412
- else
413
- vt = exprtype (rhs, sv)
414
- end
415
- vt = widenconst (vt)
408
+ vt = widenconst (sv. src. ssavaluetypes[i])
416
409
if vt != = Bottom
417
410
id = slot_id (lhs)
418
411
otherTy = slottypes[id]
517
510
518
511
# widen all Const elements in type annotations
519
512
function _widen_all_consts! (e:: Expr , untypedload:: Vector{Bool} , slottypes:: Vector{Any} )
520
- e. typ = widenconst (e. typ)
521
513
for i = 1 : length (e. args)
522
514
x = e. args[i]
523
515
if isa (x, Expr)
@@ -704,29 +696,29 @@ function is_pure_builtin(@nospecialize(f))
704
696
end
705
697
end
706
698
707
- function statement_effect_free (@nospecialize (e), me:: InferenceState )
699
+ function statement_effect_free (@nospecialize (e), me:: InferenceState , @nospecialize (etype) )
708
700
if isa (e, Expr)
709
701
if e. head === :(= )
710
- return ! isa (e. args[1 ], GlobalRef) && effect_free (e. args[2 ], me, false )
702
+ return ! isa (e. args[1 ], GlobalRef) && effect_free (e. args[2 ], me, false , etype )
711
703
elseif e. head === :gotoifnot
712
- return effect_free (e. args[1 ], me, false )
704
+ return effect_free (e. args[1 ], me, false , etype )
713
705
end
714
706
elseif isa (e, GotoNode)
715
707
return true
716
708
end
717
- return effect_free (e, me, false )
709
+ return effect_free (e, me, false , etype )
718
710
end
719
711
720
- effect_free (@nospecialize (e), s:: InferenceState , allow_volatile:: Bool ) =
721
- effect_free (e, s. src, s. sp, allow_volatile)
712
+ effect_free (@nospecialize (e), s:: InferenceState , allow_volatile:: Bool , @nospecialize (etype) ) =
713
+ effect_free (e, s. src, s. sp, allow_volatile, etype )
722
714
723
- effect_free (@nospecialize (e), s:: OptimizationState , allow_volatile:: Bool ) =
724
- effect_free (e, s. src, s. sp, allow_volatile)
715
+ effect_free (@nospecialize (e), s:: OptimizationState , allow_volatile:: Bool , @nospecialize (etype) ) =
716
+ effect_free (e, s. src, s. sp, allow_volatile, etype )
725
717
726
718
# detect some important side-effect-free calls (allow_volatile=true)
727
719
# and some affect-free calls (allow_volatile=false) -- affect_free means the call
728
720
# cannot be affected by previous calls, except assignment nodes
729
- function effect_free (@nospecialize (e), src, spvals:: SimpleVector , allow_volatile:: Bool )
721
+ function effect_free (@nospecialize (e), src, spvals:: SimpleVector , allow_volatile:: Bool , @nospecialize (etype) )
730
722
if isa (e, GlobalRef)
731
723
return (isdefined (e. mod, e. name) && (allow_volatile || isconst (e. mod, e. name)))
732
724
elseif isa (e, Slot)
@@ -739,9 +731,9 @@ function effect_free(@nospecialize(e), src, spvals::SimpleVector, allow_volatile
739
731
end
740
732
if head === :static_parameter
741
733
# if we aren't certain enough about the type, it might be an UndefVarError at runtime
742
- return isa (e . typ , Const) || issingletontype (widenconst (e . typ ))
734
+ return isa (etype , Const) || issingletontype (widenconst (etype ))
743
735
end
744
- if e . typ === Bottom
736
+ if etype === Bottom
745
737
return false
746
738
end
747
739
ea = e. args
@@ -753,12 +745,11 @@ function effect_free(@nospecialize(e), src, spvals::SimpleVector, allow_volatile
753
745
elseif is_known_call (e, getfield, src, spvals)
754
746
nargs = length (ea)
755
747
(3 <= nargs <= 4 ) || return false
756
- et = exprtype (e, src, spvals)
757
748
# TODO : check ninitialized
758
- if ! isa (et , Const) && ! isconstType (et )
749
+ if ! isa (etype , Const) && ! isconstType (etype )
759
750
# first argument must be immutable to ensure e is affect_free
760
751
a = ea[2 ]
761
- typ = unwrap_unionall (widenconst (exprtype (a, src, spvals)))
752
+ typ = unwrap_unionall (widenconst (argextype (a, src, spvals)))
762
753
if isType (typ)
763
754
# all fields of subtypes of Type are effect-free
764
755
# (including the non-inferrable uid field)
@@ -770,7 +761,7 @@ function effect_free(@nospecialize(e), src, spvals::SimpleVector, allow_volatile
770
761
end
771
762
# fall-through
772
763
elseif is_known_call (e, _apply, src, spvals) && length (ea) > 1
773
- ft = exprtype (ea[2 ], src, spvals)
764
+ ft = argextype (ea[2 ], src, spvals)
774
765
if ! isa (ft, Const) || (! contains_is (_PURE_BUILTINS, ft. val) &&
775
766
ft. val != = Core. sizeof)
776
767
return false
@@ -781,7 +772,7 @@ function effect_free(@nospecialize(e), src, spvals::SimpleVector, allow_volatile
781
772
end
782
773
elseif head === :new
783
774
a = ea[1 ]
784
- typ = exprtype (a, src, spvals)
775
+ typ = argextype (a, src, spvals)
785
776
# `Expr(:new)` of unknown type could raise arbitrary TypeError.
786
777
typ, isexact = instanceof_tfunc (typ)
787
778
isexact || return false
@@ -792,7 +783,7 @@ function effect_free(@nospecialize(e), src, spvals::SimpleVector, allow_volatile
792
783
end
793
784
fieldcount (typ) >= length (ea) - 1 || return false
794
785
for fld_idx in 1 : (length (ea) - 1 )
795
- eT = exprtype (ea[fld_idx + 1 ], src, spvals)
786
+ eT = argextype (ea[fld_idx + 1 ], src, spvals)
796
787
fT = fieldtype (typ, fld_idx)
797
788
eT ⊑ fT || return false
798
789
end
@@ -809,7 +800,7 @@ function effect_free(@nospecialize(e), src, spvals::SimpleVector, allow_volatile
809
800
return false
810
801
end
811
802
for a in ea
812
- if ! effect_free (a, src, spvals, allow_volatile)
803
+ if ! effect_free (a, src, spvals, allow_volatile, argextype (a, src, spvals) )
813
804
return false
814
805
end
815
806
end
@@ -845,19 +836,20 @@ function statement_cost(ex::Expr, line::Int, src::CodeInfo, spvals::SimpleVector
845
836
argcost = 0
846
837
for a in ex. args
847
838
if a isa Expr
848
- argcost = plus_saturate (argcost, statement_cost (a, line , src, spvals, params))
839
+ argcost = plus_saturate (argcost, statement_cost (a, - 1 , src, spvals, params))
849
840
end
850
841
end
851
842
if head == :return || head == :(= )
852
843
return argcost
853
844
end
845
+ extyp = line == - 1 ? Any : src. ssavaluetypes[line]
854
846
if head == :call
855
- extyp = exprtype (ex. args[1 ], src, spvals)
856
- if isa (extyp , Type)
847
+ ftyp = argextype (ex. args[1 ], src, spvals)
848
+ if isa (ftyp , Type)
857
849
return argcost
858
850
end
859
- if isa (extyp , Const)
860
- f = (extyp :: Const ). val
851
+ if isa (ftyp , Const)
852
+ f = (ftyp :: Const ). val
861
853
if isa (f, IntrinsicFunction)
862
854
iidx = Int (reinterpret (Int32, f:: IntrinsicFunction )) + 1
863
855
if ! isassigned (T_IFUNC_COST, iidx)
@@ -869,15 +861,15 @@ function statement_cost(ex::Expr, line::Int, src::CodeInfo, spvals::SimpleVector
869
861
if isa (f, Builtin)
870
862
# The efficiency of operations like a[i] and s.b
871
863
# depend strongly on whether the result can be
872
- # inferred, so check ex.typ
864
+ # inferred, so check the type of ex
873
865
if f == Main. Core. getfield || f == Main. Core. tuple
874
866
# we might like to penalize non-inferrability, but
875
867
# tuple iteration/destructuring makes that
876
868
# impossible
877
- # return plus_saturate(argcost, isknowntype(ex.typ ) ? 1 : params.inline_nonleaf_penalty)
869
+ # return plus_saturate(argcost, isknowntype(extyp ) ? 1 : params.inline_nonleaf_penalty)
878
870
return argcost
879
871
elseif f == Main. Core. arrayref
880
- return plus_saturate (argcost, isknowntype (ex . typ ) ? 4 : params. inline_nonleaf_penalty)
872
+ return plus_saturate (argcost, isknowntype (extyp ) ? 4 : params. inline_nonleaf_penalty)
881
873
end
882
874
fidx = findfirst (x-> x=== f, T_FFUNC_KEY)
883
875
if fidx === nothing
@@ -895,7 +887,7 @@ function statement_cost(ex::Expr, line::Int, src::CodeInfo, spvals::SimpleVector
895
887
# run-time of the function, we omit them from
896
888
# consideration. This way, non-inlined error branches do not
897
889
# prevent inlining.
898
- return ex . typ == Union{} ? 0 : plus_saturate (20 , argcost)
890
+ return extyp == Union{} ? 0 : plus_saturate (20 , argcost)
899
891
elseif head == :llvmcall
900
892
return plus_saturate (10 , argcost) # a wild guess at typical cost
901
893
elseif head == :enter
@@ -935,38 +927,19 @@ function inline_worthy(body::Array{Any,1}, src::CodeInfo, spvals::SimpleVector,
935
927
return bodycost <= cost_threshold
936
928
end
937
929
938
- function inline_worthy (body:: Expr , src:: CodeInfo , spvals:: SimpleVector , params:: Params ,
939
- cost_threshold:: Integer = params. inline_cost_threshold)
940
- bodycost = statement_cost (body, typemax (Int), src, spvals, params)
941
- return bodycost <= cost_threshold
942
- end
943
-
944
- function inline_worthy (@nospecialize (body), src:: CodeInfo , spvals:: SimpleVector , params:: Params ,
945
- cost_threshold:: Integer = params. inline_cost_threshold)
946
- newbody = exprtype (body, src, spvals)
947
- ! isa (newbody, Expr) && return true
948
- return inline_worthy (newbody, src, spvals, params, cost_threshold)
949
- end
950
-
951
- function mk_tuplecall (args, sv:: OptimizationState )
952
- e = Expr (:call , TOP_TUPLE, args... )
953
- e. typ = tuple_tfunc (Tuple{Any[widenconst (exprtype (x, sv)) for x in args]. .. })
954
- return e
955
- end
956
-
957
930
function is_known_call (e:: Expr , @nospecialize (func), src, spvals)
958
931
if e. head != = :call
959
932
return false
960
933
end
961
- f = exprtype (e. args[1 ], src, spvals)
934
+ f = argextype (e. args[1 ], src, spvals)
962
935
return isa (f, Const) && f. val === func
963
936
end
964
937
965
938
function is_known_call_p (e:: Expr , @nospecialize (pred), src, spvals)
966
939
if e. head != = :call
967
940
return false
968
941
end
969
- f = exprtype (e. args[1 ], src, spvals)
942
+ f = argextype (e. args[1 ], src, spvals)
970
943
return (isa (f, Const) && pred (f. val)) || (isType (f) && pred (f. parameters[1 ]))
971
944
end
972
945
0 commit comments