diff --git a/Project.toml b/Project.toml index 8ff3802e0..742713f76 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "SnoopCompile" uuid = "aa65fe97-06da-5843-b5b1-d5d13cad87d2" author = ["Tim Holy ", "Shuhei Kadowaki "] -version = "3.0.3" +version = "3.1.0" [deps] AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" diff --git a/src/utils.jl b/src/utils.jl index 77b19a073..c1ecc3b18 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -61,7 +61,7 @@ let known_type_cache = IdDict{Tuple{Module,Tuple{Vararg{Symbol}},Symbol},Bool}() end end -function add_repr!(list, modgens::Dict{Module, Vector{Method}}, mi::MethodInstance, topmod::Module=mi.def.module; check_eval::Bool, time=nothing, kwargs...) +function add_repr!(list, modgens::Dict{Module, Vector{Method}}, mi::MethodInstance, topmod::Module=mi.def.module; check_eval::Bool, time=nothing, suppress_time::Bool=false, kwargs...) # Create the string representation of the signature # Use special care with keyword functions, anonymous functions tt = Base.unwrap_unionall(mi.specTypes) @@ -83,9 +83,9 @@ function add_repr!(list, modgens::Dict{Module, Vector{Method}}, mi::MethodInstan # Keyword function fname = mkw.captures[1] === nothing ? mkw.captures[2] : mkw.captures[1] fkw = "Core.kwftype(typeof($fname))" - return add_if_evals!(list, topmod, fkw, paramrepr, tt; check_eval=check_eval, time=time) + return add_if_evals!(list, topmod, fkw, paramrepr, tt; check_eval, time, suppress_time) elseif mkwbody !== nothing - ret = handle_kwbody(topmod, m, paramrepr, tt; check_eval = check_eval, kwargs...) + ret = handle_kwbody(topmod, m, paramrepr, tt; check_eval, kwargs...) if ret !== nothing push!(list, append_time(ret, time)) return true @@ -107,7 +107,7 @@ function add_repr!(list, modgens::Dict{Module, Vector{Method}}, mi::MethodInstan mkwc = match(kwbodyrex, cname) if mkwc === nothing getgen = "typeof(which($(caller.name),$csigstr).generator.gen)" - return add_if_evals!(list, topmod, getgen, paramrepr, tt; check_eval=check_eval, time=time) + return add_if_evals!(list, topmod, getgen, paramrepr, tt; check_eval, time, suppress_time) else getgen = "which(Core.kwfunc($(mkwc.captures[1])),$csigstr).generator.gen" ret = handle_kwbody(topmod, caller, cparamrepr, tt; check_eval = check_eval, kwargs...) #, getgen) @@ -123,9 +123,9 @@ function add_repr!(list, modgens::Dict{Module, Vector{Method}}, mi::MethodInstan # Anonymous function, wrap in an `isdefined` prefix = "isdefined($mmod, Symbol(\"$mname\")) && " fstr = "getfield($mmod, Symbol(\"$mname\"))" # this is universal, var is Julia 1.3+ - return add_if_evals!(list, topmod, fstr, paramrepr, tt; prefix=prefix, check_eval = check_eval, time=time) + return add_if_evals!(list, topmod, fstr, paramrepr, tt; prefix, check_eval, time, suppress_time) end - return add_if_evals!(list, topmod, reprcontext(topmod, p), paramrepr, tt, check_eval = check_eval, time=time) + return add_if_evals!(list, topmod, reprcontext(topmod, p), paramrepr, tt; check_eval, time, suppress_time) end function handle_kwbody(topmod::Module, m::Method, paramrepr, tt, fstr="fbody"; check_eval = true) @@ -195,11 +195,15 @@ Adds the precompilation statements only if they can be evaled. It uses [`can_eva In some cases, you may want to bypass this function by passing `check_eval=true` to increase the snooping performance. """ -function add_if_evals!(pclist, mod::Module, fstr, params, tt; prefix = "", check_eval::Bool=true, time=nothing) +function add_if_evals!(pclist, mod::Module, fstr, params, tt; prefix = "", check_eval::Bool=true, time=nothing, suppress_time::Bool=false) ttstr = tupletypestring(fstr, params) can, exc = can_eval(mod, ttstr, check_eval) if can - push!(pclist, append_time(prefix*wrap_precompile(ttstr), time)) + str = prefix*wrap_precompile(ttstr) + if !suppress_time + str = append_time(str, time) + end + push!(pclist, str) return true else @debug "Module $mod: skipping $tt due to eval failure" exception=exc _module=mod _file="precompile_$mod.jl" diff --git a/src/write.jl b/src/write.jl index 287670460..dd2eab390 100644 --- a/src/write.jl +++ b/src/write.jl @@ -32,14 +32,6 @@ function write(filename::AbstractString, pc::Vector; kwargs...) end end -""" - write(prefix::AbstractString, pc::Dict; always::Bool = false) - -Write each modules' precompiles to a separate file. If `always` is -true, the generated function will always run the precompile statements -when called, otherwise the statements will only be called during -package precompilation. -""" function write(prefix::AbstractString, pc::Dict; always::Bool = false) if !isdir(prefix) mkpath(prefix) @@ -59,3 +51,18 @@ function write(prefix::AbstractString, pc::Dict; always::Bool = false) end end end + +@doc """ + write(prefix::AbstractString, pc; always::Bool=false, suppress_time::Bool=false) + +Write each modules' precompiles to a separate file. If `always` is true, the +generated function will always run the precompile statements when called, +otherwise the statements will only be called during package precompilation. + +When writing results from parceling `@snoop_inference`, by default SnoopCompile +appends the time taken to precompile each statement to the generated file. If +`suppress_time` is true, this information will be omitted. + +!!! compat "SnoopCompile 3.1" + The `suppress_time` keyword argument was added in SnoopCompile 3.1. +""" write diff --git a/test/snoop_inference.jl b/test/snoop_inference.jl index 6df6a001b..1a9a84497 100644 --- a/test/snoop_inference.jl +++ b/test/snoop_inference.jl @@ -748,6 +748,12 @@ include("testmodules/SnoopBench.jl") str = String(take!(io)) @test occursin(r"typeof\(mappushes\),Any,Vector\{A\}", str) @test occursin(r"typeof\(mappushes!\),typeof\(identity\),Vector\{Any\},Vector\{A\}", str) + @test occursin(r"# time: \d", str) + SnoopCompile.write(io, tmis; tmin=0.0, suppress_time=true) + str = String(take!(io)) + @test occursin(r"typeof\(mappushes\),Any,Vector\{A\}", str) + @test occursin(r"typeof\(mappushes!\),typeof\(identity\),Vector\{Any\},Vector\{A\}", str) + @test !occursin(r"# time: \d", str) list = Any[1, 1.0, Float16(1.0), a] tinf = @snoop_inference SnoopBench.mappushes(isequal(Int8(1)), list)