Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "SnoopCompile"
uuid = "aa65fe97-06da-5843-b5b1-d5d13cad87d2"
author = ["Tim Holy <[email protected]>", "Shuhei Kadowaki <[email protected]>"]
version = "3.0.3"
version = "3.1.0"

[deps]
AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c"
Expand Down
20 changes: 12 additions & 8 deletions src/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand All @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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"
Expand Down
23 changes: 15 additions & 8 deletions src/write.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
6 changes: 6 additions & 0 deletions test/snoop_inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Loading