StatProfilerHTML.jl report
Generated on ons 9 okt 2019 08:41:28
File source code
Line Exclusive Inclusive Code
1 # This file is a part of Julia. License is MIT: https://julialang.org/license
2
3 """
4 Determine whether a statement is side-effect-free, i.e. may be removed if it has no uses.
5 """
6
1 (2.70%) samples spent in stmt_effect_free
1 (100.00%) (ex.), 1 (100.00%) (incl.) when called from maybe_erase_unused! line 903
function stmt_effect_free(@nospecialize(stmt), @nospecialize(rt), src, spvals::SimpleVector)
7 1 (2.70%) 1 (2.70%) isa(stmt, Union{PiNode, PhiNode}) && return true
8 isa(stmt, Union{ReturnNode, GotoNode, GotoIfNot}) && return false
9 isa(stmt, GlobalRef) && return isdefined(stmt.mod, stmt.name)
10 isa(stmt, Slot) && return false # Slots shouldn't occur in the IR at this point, but let's be defensive here
11 if isa(stmt, Expr)
12 e = stmt::Expr
13 head = e.head
14 if head === :static_parameter
15 etyp = sparam_type(spvals[e.args[1]])
16 # if we aren't certain enough about the type, it might be an UndefVarError at runtime
17 return isa(etyp, Const) || issingletontype(widenconst(etyp))
18 end
19 ea = e.args
20 if head === :call
21 f = argextype(ea[1], src, spvals)
22 f = isa(f, Const) ? f.val : isType(f) ? f.parameters[1] : return false
23 f === return_type && return true
24 contains_is(_PURE_BUILTINS, f) && return true
25 contains_is(_PURE_OR_ERROR_BUILTINS, f) || return false
26 rt === Bottom && return false
27 return _builtin_nothrow(f, Any[argextype(ea[i], src, spvals) for i = 2:length(ea)], rt)
28 elseif head === :new
29 a = ea[1]
30 typ = argextype(a, src, spvals)
31 # `Expr(:new)` of unknown type could raise arbitrary TypeError.
32 typ, isexact = instanceof_tfunc(typ)
33 isexact || return false
34 isconcretedispatch(typ) || return false
35 typ = typ::DataType
36 fieldcount(typ) >= length(ea) - 1 || return false
37 for fld_idx in 1:(length(ea) - 1)
38 eT = argextype(ea[fld_idx + 1], src, spvals)
39 fT = fieldtype(typ, fld_idx)
40 eT ⊑ fT || return false
41 end
42 return true
43 elseif head === :isdefined || head === :the_exception || head === :copyast || head === :inbounds || head === :boundscheck
44 return true
45 else
46 # e.g. :simdloop
47 return false
48 end
49 end
50 return true
51 end
52
53 function abstract_eval_ssavalue(s::SSAValue, src::IRCode)
54 return types(src)[s]
55 end
56
57 function abstract_eval_ssavalue(s::SSAValue, src::IncrementalCompact)
58 return types(src)[s]
59 end
60
61 function compact_exprtype(compact::IncrementalCompact, @nospecialize(value))
62 if isa(value, AnySSAValue)
63 return types(compact)[value]
64 elseif isa(value, Argument)
65 return compact.ir.argtypes[value.n]
66 end
67 return argextype(value, compact.ir, compact.ir.spvals)
68 end
69
70 is_tuple_call(ir::IRCode, @nospecialize(def)) = isa(def, Expr) && is_known_call(def, tuple, ir, ir.spvals)
71 is_tuple_call(compact::IncrementalCompact, @nospecialize(def)) = isa(def, Expr) && is_known_call(def, tuple, compact)
72 function is_known_call(e::Expr, @nospecialize(func), src::IncrementalCompact)
73 if e.head !== :call
74 return false
75 end
76 f = compact_exprtype(src, e.args[1])
77 return isa(f, Const) && f.val === func
78 end