Skip to content

Commit

Permalink
change how istopfunction works to pass around Modules less in optim…
Browse files Browse the repository at this point in the history
…izer
  • Loading branch information
JeffBezanson committed Jun 12, 2018
1 parent 83a0dd7 commit f9d4d7f
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 26 deletions.
17 changes: 8 additions & 9 deletions base/compiler/abstractinterpretation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ function abstract_call_method_with_const_args(@nospecialize(f), argtypes::Vector
end
if !cache_inlineable && !sv.params.aggressive_constant_propagation
tm = _topmod(sv)
if !istopfunction(tm, f, :getproperty) && !istopfunction(tm, f, :setproperty!)
if !istopfunction(f, :getproperty) && !istopfunction(f, :setproperty!)
# in this case, see if all of the arguments are constants
for a in argtypes
if !isa(a, Const) && !isconstType(a)
Expand Down Expand Up @@ -499,7 +499,6 @@ function abstract_call(@nospecialize(f), fargs::Union{Tuple{},Vector{Any}}, argt
end
end

tm = _topmod(sv)
if isa(f, Builtin) || isa(f, IntrinsicFunction)
if f === ifelse && fargs isa Vector{Any} && length(argtypes) == 4 && argtypes[2] isa Conditional
cnd = argtypes[2]
Expand Down Expand Up @@ -640,14 +639,14 @@ function abstract_call(@nospecialize(f), fargs::Union{Tuple{},Vector{Any}}, argt
if rt_rt !== NOT_FOUND
return rt_rt
end
elseif length(argtypes) == 2 && istopfunction(tm, f, :!)
elseif length(argtypes) == 2 && istopfunction(f, :!)
# handle Conditional propagation through !Bool
aty = argtypes[2]
if isa(aty, Conditional)
abstract_call_gf_by_type(f, Any[Const(f), Bool], Tuple{typeof(f), Bool}, sv) # make sure we've inferred `!(::Bool)`
return Conditional(aty.var, aty.elsetype, aty.vtype)
end
elseif length(argtypes) == 3 && istopfunction(tm, f, :!==)
elseif length(argtypes) == 3 && istopfunction(f, :!==)
# mark !== as exactly a negated call to ===
rty = abstract_call((===), fargs, argtypes, vtypes, sv)
if isa(rty, Conditional)
Expand All @@ -656,7 +655,7 @@ function abstract_call(@nospecialize(f), fargs::Union{Tuple{},Vector{Any}}, argt
return Const(rty.val === false)
end
return rty
elseif length(argtypes) == 3 && istopfunction(tm, f, :(>:))
elseif length(argtypes) == 3 && istopfunction(f, :(>:))
# mark issupertype as a exact alias for issubtype
# swap T1 and T2 arguments and call <:
if length(fargs) == 3
Expand All @@ -667,26 +666,26 @@ function abstract_call(@nospecialize(f), fargs::Union{Tuple{},Vector{Any}}, argt
argtypes = Any[typeof(<:), argtypes[3], argtypes[2]]
rty = abstract_call(<:, fargs, argtypes, vtypes, sv)
return rty
elseif length(argtypes) == 2 && isa(argtypes[2], Const) && isa(argtypes[2].val, SimpleVector) && istopfunction(tm, f, :length)
elseif length(argtypes) == 2 && isa(argtypes[2], Const) && isa(argtypes[2].val, SimpleVector) && istopfunction(f, :length)
# mark length(::SimpleVector) as @pure
return Const(length(argtypes[2].val))
elseif length(argtypes) == 3 && isa(argtypes[2], Const) && isa(argtypes[3], Const) &&
isa(argtypes[2].val, SimpleVector) && isa(argtypes[3].val, Int) && istopfunction(tm, f, :getindex)
isa(argtypes[2].val, SimpleVector) && isa(argtypes[3].val, Int) && istopfunction(f, :getindex)
# mark getindex(::SimpleVector, i::Int) as @pure
svecval = argtypes[2].val::SimpleVector
idx = argtypes[3].val::Int
if 1 <= idx <= length(svecval) && isassigned(svecval, idx)
return Const(getindex(svecval, idx))
end
elseif length(argtypes) == 2 && istopfunction(tm, f, :typename)
elseif length(argtypes) == 2 && istopfunction(f, :typename)
return typename_static(argtypes[2])
end

atype = argtypes_to_type(argtypes)
t = pure_eval_call(f, argtypes, atype, sv)
t !== false && return t

if istopfunction(tm, f, :typejoin) || f === return_type
if istopfunction(f, :typejoin) || f === return_type
return Type # don't try to infer these function edges directly -- it won't actually come up with anything useful
end

Expand Down
25 changes: 13 additions & 12 deletions base/compiler/ssair/inlining2.jl
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,9 @@ function ir_inline_item!(compact::IncrementalCompact, idx::Int, argexprs::Vector
return_value
end

function ir_inline_unionsplit!(compact::IncrementalCompact, topmod::Module, idx::Int,
const fatal_type_bound_error = ErrorException("fatal error in type inference (type bound)")

function ir_inline_unionsplit!(compact::IncrementalCompact, idx::Int,
argexprs::Vector{Any}, linetable::Vector{LineInfoNode},
item::UnionSplit, boundscheck::Symbol, todo_bbs::Vector{Tuple{Int, Int}})
stmt, typ, line = compact.result[idx], compact.result_types[idx], compact.result_lines[idx]
Expand Down Expand Up @@ -435,7 +437,7 @@ function ir_inline_unionsplit!(compact::IncrementalCompact, topmod::Module, idx:
bb += 1
# We're now in the fall through block, decide what to do
if item.fully_covered
e = Expr(:call, GlobalRef(topmod, :error), "fatal error in type inference (type bound)")
e = Expr(:call, GlobalRef(Core, :throw), fatal_type_bound_error)
e.typ = Union{}
insert_node_here!(compact, e, Union{}, line)
insert_node_here!(compact, ReturnNode(), Union{}, line)
Expand Down Expand Up @@ -504,7 +506,7 @@ function batch_inline!(todo::Vector{Any}, ir::IRCode, linetable::Vector{LineInfo
if isa(item, InliningTodo)
compact.ssa_rename[compact.idx-1] = ir_inline_item!(compact, idx, argexprs, linetable, item, boundscheck, state.todo_bbs)
elseif isa(item, UnionSplit)
ir_inline_unionsplit!(compact, _topmod(sv.mod), idx, argexprs, linetable, item, boundscheck, state.todo_bbs)
ir_inline_unionsplit!(compact, idx, argexprs, linetable, item, boundscheck, state.todo_bbs)
end
compact[idx] = nothing
refinish && finish_current_bb!(compact)
Expand Down Expand Up @@ -839,7 +841,7 @@ function assemble_inline_todo!(ir::IRCode, linetable::Vector{LineInfoNode}, sv::
sv.params.inlining || continue

# Special case inliners for regular functions
if late_inline_special_case!(ir, idx, stmt, atypes, f, ft, _topmod(ir.mod))
if late_inline_special_case!(ir, idx, stmt, atypes, f, ft)
continue
end

Expand Down Expand Up @@ -1006,17 +1008,16 @@ function early_inline_special_case(ir::IRCode, @nospecialize(f), @nospecialize(f
return val
end
end
topmod = _topmod(ir.mod)
# special-case inliners for known pure functions that compute types
if sv.params.inlining
if isa(e.typ, Const) # || isconstType(e.typ)
val = e.typ.val
if (f === apply_type || f === fieldtype || f === typeof || f === (===) ||
f === Core.sizeof || f === isdefined ||
istopfunction(topmod, f, :typejoin) ||
istopfunction(topmod, f, :isbits) ||
istopfunction(topmod, f, :isbitstype) ||
istopfunction(topmod, f, :promote_type) ||
istopfunction(f, :typejoin) ||
istopfunction(f, :isbits) ||
istopfunction(f, :isbitstype) ||
istopfunction(f, :promote_type) ||
(f === Core.kwfunc && length(atypes) == 2) ||
(is_inlineable_constant(val) &&
(contains_is(_PURE_BUILTINS, f) ||
Expand All @@ -1030,8 +1031,8 @@ function early_inline_special_case(ir::IRCode, @nospecialize(f), @nospecialize(f
return nothing
end

function late_inline_special_case!(ir::IRCode, idx::Int, stmt::Expr, atypes::Vector{Any}, @nospecialize(f), @nospecialize(ft), topmod::Module)
if length(atypes) == 3 && istopfunction(topmod, f, :!==)
function late_inline_special_case!(ir::IRCode, idx::Int, stmt::Expr, atypes::Vector{Any}, @nospecialize(f), @nospecialize(ft))
if length(atypes) == 3 && istopfunction(f, :!==)
# special-case inliner for !== that precedes _methods_by_ftype union splitting
# and that works, even though inference generally avoids inferring the `!==` Method
if isa(stmt.typ, Const)
Expand All @@ -1045,7 +1046,7 @@ function late_inline_special_case!(ir::IRCode, idx::Int, stmt::Expr, atypes::Vec
not_call.typ = Bool
ir[SSAValue(idx)] = not_call
return true
elseif length(atypes) == 3 && istopfunction(topmod, f, :(>:))
elseif length(atypes) == 3 && istopfunction(f, :(>:))
# special-case inliner for issupertype
# that works, even though inference generally avoids inferring the `>:` Method
if isa(stmt.typ, Const)
Expand Down
10 changes: 5 additions & 5 deletions base/compiler/utilities.jl
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ anymap(f::Function, a::Array{Any,1}) = Any[ f(a[i]) for i in 1:length(a) ]

_topmod(m::Module) = ccall(:jl_base_relative_to, Any, (Any,), m)::Module

function istopfunction(topmod, @nospecialize(f), sym)
if isdefined(Main, :Base) && isdefined(Main.Base, sym) && isconst(Main.Base, sym) && f === getfield(Main.Base, sym)
return true
elseif isdefined(topmod, sym) && isconst(topmod, sym) && f === getfield(topmod, sym)
return true
function istopfunction(@nospecialize(f), name::Symbol)
tn = typeof(f).name
if tn.mt.name === name
top = _topmod(tn.module)
return isdefined(top, name) && isconst(top, name) && f === getfield(top, name)
end
return false
end
Expand Down

0 comments on commit f9d4d7f

Please sign in to comment.