@@ -6,7 +6,7 @@ const MAX_TYPE_DEPTH = 5
6
6
const MAX_TUPLETYPE_LEN = 8
7
7
const MAX_TUPLE_DEPTH = 4
8
8
9
- type NotFound
9
+ immutable NotFound
10
10
end
11
11
12
12
const NF = NotFound ()
@@ -535,7 +535,7 @@ function builtin_tfunction(f::ANY, args::ANY, argtype::ANY, vtypes::ObjectIdDict
535
535
return tf[3 ](argtypes... )
536
536
end
537
537
538
- function isconstantfunc (f:: ANY , sv:: StaticVarInfo )
538
+ function isconstantref (f:: ANY , sv:: StaticVarInfo )
539
539
if isa (f,TopNode)
540
540
m = _topmod ()
541
541
return isconst (m, f. name) && isdefined (m, f. name) && f
@@ -544,39 +544,46 @@ function isconstantfunc(f::ANY, sv::StaticVarInfo)
544
544
M = f. mod; s = f. name
545
545
return isdefined (M,s) && isconst (M,s) && f
546
546
end
547
- if isa (f,Expr) && is (f. head,:call )
548
- if length (f. args) == 3 && isa (f. args[1 ], TopNode) &&
549
- is (f. args[1 ]. name,:getfield ) && isa (f. args[3 ],QuoteNode)
550
- s = f. args[3 ]. value
551
- if isa (f. args[2 ],Module)
552
- M = f. args[2 ]
553
- else
554
- M = isconstantfunc (f. args[2 ], sv)
555
- if M === false
556
- return false
557
- end
558
- M = _ieval (M)
559
- if ! isa (M,Module)
560
- return false
547
+ if isa (f,Expr)
548
+ if is (f. head,:call )
549
+ if length (f. args) == 3 && isa (f. args[1 ], TopNode) &&
550
+ is (f. args[1 ]. name,:getfield ) && isa (f. args[3 ],QuoteNode)
551
+ s = f. args[3 ]. value
552
+ if isa (f. args[2 ],Module)
553
+ M = f. args[2 ]
554
+ else
555
+ M = isconstantref (f. args[2 ], sv)
556
+ if M === false
557
+ return false
558
+ end
559
+ M = _ieval (M)
560
+ if ! isa (M,Module)
561
+ return false
562
+ end
561
563
end
564
+ return isdefined (M,s) && isconst (M,s) && f
562
565
end
563
- return isdefined (M,s) && isconst (M,s) && f
566
+ elseif is (f. head,:inert )
567
+ return f
564
568
end
569
+ return false
565
570
end
566
-
567
- if isa (f,QuoteNode) && (isa (f. value, Function) || isa (f. value, IntrinsicFunction))
568
- return f. value
569
- end
570
- if isa (f,Function) || isa (f,IntrinsicFunction)
571
+ if isa (f,QuoteNode)
571
572
return f
572
573
end
573
574
if isa (f,SymbolNode)
574
575
f = f. name
575
576
end
576
- return isa (f,Symbol) && is_global (sv, f) && _iisconst (f) && f
577
+ if isa (f,Symbol)
578
+ return is_global (sv, f) && _iisconst (f) && f
579
+ end
580
+ if isa (f,GenSym) || isa (f,LambdaStaticData)
581
+ return false
582
+ end
583
+ return f
577
584
end
578
585
579
- const isconstantref = isconstantfunc
586
+ const isconstantfunc = isconstantref
580
587
581
588
const limit_tuple_depth = t-> limit_tuple_depth_ (t,0 )
582
589
@@ -651,25 +658,7 @@ function abstract_call_gf(f, fargs, argtype, e)
651
658
end
652
659
end
653
660
if istopfunction (tm, f, :promote_type ) || istopfunction (tm, f, :typejoin )
654
- la = length (argtypes)
655
- c = cell (la)
656
- for i = 1 : la
657
- t = argtypes[i]
658
- if isType (t) && ! isa (t. parameters[1 ],TypeVar)
659
- c[i] = t. parameters[1 ]
660
- else
661
- return Type
662
- end
663
- end
664
- if istopfunction (tm, f, :promote_type )
665
- try
666
- RT = Type{f (c... )}
667
- return RT
668
- catch
669
- end
670
- else
671
- return Type{f (c... )}
672
- end
661
+ return Type
673
662
end
674
663
# don't consider more than N methods. this trades off between
675
664
# compiler performance and generated code performance.
@@ -822,7 +811,109 @@ function abstract_apply(af, fargs, aargtypes::Vector{Any}, vtypes, sv, e)
822
811
return abstract_call (af, (), Any[Vararg{Any}], vtypes, sv, ())
823
812
end
824
813
814
+ function isconstantargs (args, argtypes:: Vector{Any} , sv:: StaticVarInfo )
815
+ if isempty (argtypes)
816
+ return true
817
+ end
818
+ if is (args,()) || isa (argtypes[end ], Vararg)
819
+ return false
820
+ end
821
+ for i = 1 : length (args)
822
+ arg = args[i]
823
+ t = argtypes[i]
824
+ if ! isType (t) || has_typevars (t. parameters[1 ])
825
+ if isconstantref (arg, sv) === false
826
+ return false
827
+ end
828
+ end
829
+ end
830
+ return true
831
+ end
832
+
833
+ function _ieval_args (args, argtypes:: Vector{Any} , sv:: StaticVarInfo )
834
+ c = cell (length (args))
835
+ for i = 1 : length (argtypes)
836
+ t = argtypes[i]
837
+ if isType (t) && ! has_typevars (t. parameters[1 ])
838
+ c[i] = t. parameters[1 ]
839
+ else
840
+ c[i] = _ieval (isconstantref (args[i], sv))
841
+ end
842
+ end
843
+ return c
844
+ end
845
+
846
+ @pure function type_typeof (v:: ANY )
847
+ if isa (v, Type)
848
+ return Type{v}
849
+ end
850
+ return typeof (v)
851
+ end
852
+
853
+ function pure_eval_call (f, fargs, argtypes, sv, e)
854
+ if ! isa (f, Function) # TODO : maybe replace with :call?
855
+ return false
856
+ end
857
+ if ! isconstantargs (fargs, argtypes, sv)
858
+ return false
859
+ end
860
+
861
+ args = _ieval_args (fargs, argtypes, sv)
862
+ tm = _topmod ()
863
+ if isgeneric (f)
864
+ atype = Tuple{Any[type_typeof (a) for a in args]. .. }
865
+ meth = _methods (f, atype, 1 )
866
+ if meth === false || length (meth) != 1
867
+ return false
868
+ end
869
+ meth = meth[1 ]:: SimpleVector
870
+ linfo = try
871
+ func_for_method (meth[3 ], atype, meth[2 ])
872
+ catch
873
+ NF
874
+ end
875
+ if linfo === NF
876
+ return false
877
+ end
878
+ if ! linfo. pure
879
+ typeinf (linfo, meth[1 ], meth[2 ], linfo)
880
+ if ! linfo. pure
881
+ return false
882
+ end
883
+ end
884
+ elseif ! isdefined (f, :code ) || ! f. code. pure
885
+ return false
886
+ end
887
+
888
+ local v
889
+ try
890
+ v = f (args... )
891
+ catch
892
+ return false
893
+ end
894
+ if isa (e, Expr) # replace Expr with a constant
895
+ stmts = Any[] # check if any arguments aren't effect_free and need to be kept around
896
+ for i = 1 : length (fargs)
897
+ arg = fargs[i]
898
+ if ! effect_free (arg, sv, false )
899
+ push! (stmts, arg)
900
+ end
901
+ end
902
+ if isempty (stmts)
903
+ e. head = :inert # eval_annotate will turn this into a QuoteNode
904
+ e. args = Any[v]
905
+ else
906
+ e. head = :call # should get cleaned up by tuple elimination
907
+ e. args = Any[top_getfield, Expr (:call , top_tuple, stmts... , v), length (stmts) + 1 ]
908
+ end
909
+ end
910
+ return type_typeof (v)
911
+ end
912
+
913
+
825
914
function abstract_call (f, fargs, argtypes:: Vector{Any} , vtypes, sv:: StaticVarInfo , e)
915
+ t = pure_eval_call (f, fargs, argtypes, sv, e)
916
+ t != = false && return t
826
917
if is (f,_apply) && length (fargs)> 1
827
918
af = isconstantfunc (fargs[2 ], sv)
828
919
if ! is (af,false )
@@ -926,7 +1017,8 @@ function abstract_eval_call(e, vtypes, sv::StaticVarInfo)
926
1017
if ! (Function <: ft ) && _iisdefined (:call )
927
1018
call_func = _ieval (:call )
928
1019
if isa (call_func,Function)
929
- return abstract_call (call_func, e. args, Any[ft,argtypes... ], vtypes, sv, e)
1020
+ unshift! (argtypes, ft)
1021
+ return abstract_call (call_func, e. args, argtypes, vtypes, sv, e)
930
1022
end
931
1023
end
932
1024
return Any
943
1035
944
1036
function abstract_eval (e:: ANY , vtypes, sv:: StaticVarInfo )
945
1037
if isa (e,QuoteNode)
946
- return typeof ((e:: QuoteNode ). value)
1038
+ v = (e:: QuoteNode ). value
1039
+ return type_typeof (v)
947
1040
elseif isa (e,TopNode)
948
1041
return abstract_eval_global (_topmod (), (e:: TopNode ). name)
949
1042
elseif isa (e,Symbol)
@@ -1019,6 +1112,9 @@ function abstract_eval(e::ANY, vtypes, sv::StaticVarInfo)
1019
1112
t = Function
1020
1113
elseif is (e. head,:copyast )
1021
1114
t = abstract_eval (e. args[1 ], vtypes, sv)
1115
+ elseif is (e. head,:inert )
1116
+ v = e. args[1 ]
1117
+ return type_typeof (v)
1022
1118
else
1023
1119
t = Any
1024
1120
end
@@ -1713,6 +1809,9 @@ function typeinf_uncached(linfo::LambdaStaticData, atypes::ANY, sparams::SimpleV
1713
1809
getfield_elim_pass (fulltree. args[3 ], sv)
1714
1810
end
1715
1811
linfo. inferred = true
1812
+ body = Expr (:block )
1813
+ body. args = fulltree. args[3 ]. args:: Array{Any,1}
1814
+ linfo. pure = popmeta! (body, :pure )[1 ]
1716
1815
fulltree = ccall (:jl_compress_ast , Any, (Any,Any), def, fulltree)
1717
1816
end
1718
1817
@@ -1779,6 +1878,8 @@ function eval_annotate(e::ANY, vtypes::ANY, sv::StaticVarInfo, decls, clo, undef
1779
1878
return e
1780
1879
# elseif is(head,:gotoifnot) || is(head,:return)
1781
1880
# e.typ = Any
1881
+ elseif is (head,:inert )
1882
+ return QuoteNode (e. args[1 ])
1782
1883
elseif is (head,:(= ))
1783
1884
# e.typ = Any
1784
1885
s = e. args[1 ]
@@ -1968,10 +2069,7 @@ function exprtype(x::ANY, sv::StaticVarInfo)
1968
2069
return abstract_eval (x:: Symbol , emptydict, sv)
1969
2070
elseif isa (x,QuoteNode)
1970
2071
v = (x:: QuoteNode ). value
1971
- if isa (v,Type)
1972
- return Type{v}
1973
- end
1974
- return typeof (v)
2072
+ return type_typeof (v)
1975
2073
elseif isa (x,Type)
1976
2074
return Type{x}
1977
2075
elseif isa (x,LambdaStaticData)
@@ -2033,7 +2131,7 @@ function effect_free(e::ANY, sv, allow_volatile::Bool)
2033
2131
allow_volatile && return true
2034
2132
return isconst (e. mod, e. name)
2035
2133
end
2036
- if isconstantfunc (e, sv) != = false
2134
+ if isconstantref (e, sv) != = false
2037
2135
return true
2038
2136
end
2039
2137
if isa (e,Expr)
0 commit comments