From dd82ffe70eba58e87926dcf4de3fe6de84e4bc26 Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Wed, 7 Aug 2013 01:14:24 -0400 Subject: [PATCH] add custom inliner for isbits(). fixes #3938 --- base/inference.jl | 29 ++++++++++++++++++----------- base/reflection.jl | 2 +- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/base/inference.jl b/base/inference.jl index 7cb8d5f41e52d..bd0dc43be7c79 100644 --- a/base/inference.jl +++ b/base/inference.jl @@ -1667,20 +1667,27 @@ function inlineable(f, e::Expr, sv, enclosing_ast) return (e.args[3],()) end end - # special-case inliners for known pure functions that compute types - if (is(f,apply_type) || is(f,fieldtype) || - (isdefined(Main.Base,:typejoin) && is(f,Main.Base.typejoin)) || - (isdefined(Main.Base,:promote_type) && is(f,Main.Base.promote_type))) && - isType(e.typ) && isleaftype(e.typ.parameters[1]) - return (e.typ.parameters[1],()) - end if length(atypes)==2 && is(f,unbox) && isa(atypes[2],DataType) + # remove redundant unbox return (e.args[3],()) end - if is(f,Union) && isType(e.typ) - union = e.typ.parameters[1] - if isa(union,UnionType) && all(isleaftype, (union::UnionType).types) - return (union,()) + # special-case inliners for known pure functions that compute types + if isType(e.typ) + if (is(f,apply_type) || is(f,fieldtype) || + (isdefined(Main.Base,:typejoin) && is(f,Main.Base.typejoin)) || + (isdefined(Main.Base,:promote_type) && is(f,Main.Base.promote_type))) && + isleaftype(e.typ.parameters[1]) + return (e.typ.parameters[1],()) + end + if isdefined(Main.Base,:isbits) && is(f,Main.Base.isbits) && + isleaftype(e.typ.parameters[1]) + return (isbits(e.typ.parameters[1]),()) + end + if is(f,Union) + union = e.typ.parameters[1] + if isa(union,UnionType) && all(isleaftype, (union::UnionType).types) + return (union,()) + end end end if isa(f,IntrinsicFunction) diff --git a/base/reflection.jl b/base/reflection.jl index 0cc777f586929..8e310aee75b55 100644 --- a/base/reflection.jl +++ b/base/reflection.jl @@ -33,7 +33,7 @@ object_id(x::ANY) = ccall(:jl_object_id, Uint, (Any,), x) const isimmutable = x->(isa(x,Tuple) || !typeof(x).mutable) isstructtype(t::DataType) = t.names!=() || (t.size==0 && !t.abstract) isstructtype(x) = false -isbits(t::DataType) = !t.mutable && t.pointerfree +isbits(t::DataType) = !t.mutable & t.pointerfree isbits(t::Type) = false isbits(x) = isbits(typeof(x)) isleaftype(t::ANY) = ccall(:jl_is_leaf_type, Int32, (Any,), t) != 0