PrecompileTools and --trace-compile

I have a simple package Test1:

module Test1

f1(x) = x + 1
f2(x) = f1(2x)
f3(x) = f1(3x)

using PrecompileTools
@compile_workload begin
  f2(1.2)
end

end # module

I load and precompile the package in an environment. I then run:

julia --trace-compile stderr -e 'using Test1; Test1.f2(1.2); Test1.f1(1.2);'

I get the output:

   :
precompile(Tuple{typeof(Test1.f2), Float64})
precompile(Tuple{typeof(Test1.f1), Float64})

Two questions:

  1. I would have expected the method Test1.f2(::Float64) to have been cached at precompilation. Why do I get a precompile(...) statement for Test1.f2 in the trace when I run this?
  2. I would have expected the method Test1.f1(::Float64) to have been compiled when I run f2(1.2), so why do I get a precompile(...) statement in the trace for Test1.f1 when I run the Test1.f1(1.2) statement?

If I add an explicit precompile(f2, (Float64,)) to Test1, the precompile statment for f2 is no longer shown on execution, as one would expect. But the one for f1 still appears, although f1 should have been precompiled due to precompilation of f2.

1 Like

f2 being compiled when f1 isn’t can be explained by f1 being inlined into f2 after methods were dispatched at compile-time. You don’t need to independently compile a method if it’s always inlined. Verify the absence of a f1 call in @code_llvm f2(1.2).

2 Likes

Fair enough. The precompile statements disappear if I annotate @noinline for all 3 of the functions.

I wouldn’t mark an offhand comment as a solution, it lowers the visibility of the thread for people who could explain the unexpected behavior for PrecompileTools, which is the primary topic.