Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support PrecompileTools on nightly #47

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 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
4 changes: 1 addition & 3 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ jobs:
fail-fast: false
matrix:
version:
- '1.0'
- '1.6'
- '1'
- '1.12'
- 'nightly'
os:
- ubuntu-latest
Expand Down
4 changes: 2 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
name = "PrecompileTools"
uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a"
authors = ["Tim Holy <[email protected]>", "t-bltg <[email protected]>", "and contributors"]
version = "1.2.1"
version = "1.3.0"

[deps]
Preferences = "21216c6a-2e73-6563-6e65-726566657250"

[compat]
Preferences = "1"
julia = "1"
julia = "1.12"

[extras]
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
Expand Down
17 changes: 4 additions & 13 deletions src/PrecompileTools.jl
Original file line number Diff line number Diff line change
@@ -1,27 +1,18 @@
module PrecompileTools

if VERSION >= v"1.6"
using Preferences
end
using Preferences

export @setup_workload, @compile_workload, @recompile_invalidations

const verbose = Ref(false) # if true, prints all the precompiles
const have_inference_tracking = isdefined(Core.Compiler, :__set_measure_typeinf)
const have_force_compile = isdefined(Base, :Experimental) && isdefined(Base.Experimental, Symbol("#@force_compile"))

function precompile_mi(mi)
function precompile_mi(mi::Core.MethodInstance)
precompile(mi.specTypes) # TODO: Julia should allow one to pass `mi` directly (would handle `invoke` properly)
verbose[] && println(mi)
return
end

include("workloads.jl")
if VERSION >= v"1.9.0-rc2"
include("invalidations.jl")
else
macro recompile_invalidations(ex::Expr)
return esc(ex)
end
end
include("invalidations.jl")

end
73 changes: 18 additions & 55 deletions src/workloads.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const newly_inferred = Core.CodeInstance[]

function workload_enabled(mod::Module)
try
Expand All @@ -11,30 +12,12 @@ function workload_enabled(mod::Module)
end
end

"""
check_edges(node)

Recursively ensure that all callees of `node` are precompiled. This is (rarely) necessary
because sometimes there is no backedge from callee to caller (xref https://github.com/JuliaLang/julia/issues/49617),
and `staticdata.c` relies on the backedge to trace back to a MethodInstance that is tagged `mi.precompiled`.
"""
function check_edges(node)
parentmi = node.mi_info.mi
for child in node.children
childmi = child.mi_info.mi
if !(isdefined(childmi, :backedges) && parentmi ∈ childmi.backedges)
precompile_mi(childmi)
end
check_edges(child)
end
end

function precompile_roots(roots)
@assert have_inference_tracking
for child in roots
precompile_mi(child.mi_info.mi)
check_edges(child)
function precompile_newly_inferred(cis)
while !isempty(cis)
ci = pop!(cis)
precompile_mi(ci.def)
end
return cis
end

"""
Expand Down Expand Up @@ -66,37 +49,21 @@ end
- indirect runtime-dispatched calls to such methods.
"""
macro compile_workload(ex::Expr)
local iscompiling = if Base.VERSION < v"1.6"
:(ccall(:jl_generating_output, Cint, ()) == 1)
else
:((ccall(:jl_generating_output, Cint, ()) == 1 && $PrecompileTools.workload_enabled(@__MODULE__)))
end
if have_force_compile
ex = quote
begin
Base.Experimental.@force_compile
$(esc(ex))
end
end
else
# Use the hack on earlier Julia versions that blocks the interpreter
ex = quote
while false end
local iscompiling = :((ccall(:jl_generating_output, Cint, ()) == 1 && $PrecompileTools.workload_enabled(@__MODULE__)))
ex = quote
begin
Base.Experimental.@force_compile
$(esc(ex))
end
end
if have_inference_tracking
ex = quote
Core.Compiler.Timings.reset_timings()
Core.Compiler.__set_measure_typeinf(true)
try
$ex
finally
Core.Compiler.__set_measure_typeinf(false)
Core.Compiler.Timings.close_current_timer()
end
$PrecompileTools.precompile_roots(Core.Compiler.Timings._timings[1].children)
ex = quote
ccall(:jl_set_newly_inferred, Cvoid, (Any,), newly_inferred)
try
$ex
finally
ccall(:jl_set_newly_inferred, Cvoid, (Any,), nothing)
end
$PrecompileTools.precompile_newly_inferred(newly_inferred)
end
return quote
if $iscompiling || $PrecompileTools.verbose[]
Expand Down Expand Up @@ -128,11 +95,7 @@ runtime dispatches (though they will be precompiled anyway if the runtime-callee
to your package).
"""
macro setup_workload(ex::Expr)
local iscompiling = if Base.VERSION < v"1.6"
:(ccall(:jl_generating_output, Cint, ()) == 1)
else
:((ccall(:jl_generating_output, Cint, ()) == 1 && $PrecompileTools.workload_enabled(@__MODULE__)))
end
local iscompiling = :((ccall(:jl_generating_output, Cint, ()) == 1 && $PrecompileTools.workload_enabled(@__MODULE__)))
# Ideally we'd like a `let` around this to prevent namespace pollution, but that seem to
# trigger inference & codegen in undesirable ways (see #16).
return quote
Expand Down
6 changes: 1 addition & 5 deletions test/PC_A/src/PC_A.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,7 @@ struct MyType
x::Int
end

if isdefined(Base, :inferencebarrier)
inferencebarrier(@nospecialize(arg)) = Base.inferencebarrier(arg)
else
inferencebarrier(@nospecialize(arg)) = Ref{Any}(arg)[]
end
inferencebarrier(@nospecialize(arg)) = Base.inferencebarrier(arg)

function call_findfirst(x, list)
# call a method defined in Base by runtime dispatch
Expand Down
Loading
Loading