# PrecompileTools doesn't cache result of workload if type unstable

**URL:** https://discourse.julialang.org/t/precompiletools-doesnt-cache-result-of-workload-if-type-unstable/102891
**Category:** General Usage
**Tags:** question, precompilation
**Created:** [August 17, 2023, 5:48am UTC](https://discourse.julialang.org/t/precompiletools-doesnt-cache-result-of-workload-if-type-unstable/102891 "2023-08-17T05:48:01Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)
#### Post date: [August 17, 2023, 5:48am UTC](https://discourse.julialang.org/t/precompiletools-doesnt-cache-result-of-workload-if-type-unstable/102891/1 "2023-08-17T05:48:01Z")

</div>

In the following minimal example, `foo()` isn’t fully precompiled (notice the precompile statement from `--trace-compile=stderr`) unless I type annotate the type unstable function from `Meshes.jl` (confirmed type unstable with `@code_warntype`).  
This is a stripped down version of a bigger problem I’m running into. From my understanding though, everything in the precompile workload should get fully compiled (caveat for invalidations, etc., but that shouldn’t be an issue here, I think).

See the precompile output first:

```plaintext
tarnon@dave:~/projects/TestProj$ julia --project=. --trace-compile=stderr -q
julia> using TestProj
[Info: Precompiling TestProj [36d4f223-0a32-46af-8d45-768600d85ced]
precompile(Tuple{typeof(Core.kwcall), NamedTuple{(:cpu_target,), Tuple{Nothing}}, typeof(Base.julia_cmd)})
precompile(Tuple{Type{NamedTuple{(:stderr, :stdout), T} where T<:Tuple}, Tuple{Base.TTY, Base.TTY}})
precompile(Tuple{typeof(Core.kwcall), NamedTuple{(:stderr, :stdout), Tuple{Base.TTY, Base.TTY}}, typeof(Base.pipeline), Base.Cmd})
precompile(Tuple{typeof(Base._tryrequire_from_serialized), Base.PkgId, String, String})
precompile(Tuple{typeof(Base.first), Array{Any, 1}})

# NOTE: shouldn't foo() be fully precompiled?
julia> foo();
precompile(Tuple{typeof(Base.:(>)), Float64, Int64})

```

MWE:

```julia
module TestProj

using PrecompileTools
using Meshes: area, hull, JarvisMarch, Point2, intersects

export foo

function foo()
    shape1 = hull([Point2(rand(2)) for i in 1:10], JarvisMarch())
    area(shape1) > 1
end

@compile_workload begin
    foo()
end

end

```

Interestingly, if I type annotate `area(shape1)::Float64`, the precompile printout goes away.

Is this a bug, invalidation or cache issue, or am I just not using PrecompileTools correctly?

---

<div class="post-metadata">

### Author: ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)
#### Post date: [August 17, 2023, 9:44am UTC](https://discourse.julialang.org/t/precompiletools-doesnt-cache-result-of-workload-if-type-unstable/102891/2 "2023-08-17T09:44:15Z")

</div>

While I was surprised myself, this is actually (or apparently) [fine](https://github.com/JuliaLang/julia/issues/50720#issuecomment-1658735614). That `>` specialization gets fully inlined, so there’s no recompilation of `foo` or anything it needs. There’s also no inference happening, as `SnoopCompileCore.@snoopi_deep` would show you. I’m still not quite sure I understand why it’s being printed, but the amount of time involved anyway is trivial. Hopefully you’re getting good results from your precompilation.

---

<div class="post-metadata">

### Author: ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)
#### Post date: [August 17, 2023, 11:40am UTC](https://discourse.julialang.org/t/precompiletools-doesnt-cache-result-of-workload-if-type-unstable/102891/3 "2023-08-17T11:40:03Z")

</div>

What would happen if the compiler is not present?

---

<div class="post-metadata">

### Author: ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)
#### Post date: [August 17, 2023, 12:57pm UTC](https://discourse.julialang.org/t/precompiletools-doesnt-cache-result-of-workload-if-type-unstable/102891/4 "2023-08-17T12:57:46Z")

</div>

It should be a no-op but I’m unsure it actually is. We’ll certainly find out one way or another when we get serious about working on static compilation…

---

<div class="post-metadata">

### Author: ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)
#### Post date: [August 17, 2023, 7:11pm UTC](https://discourse.julialang.org/t/precompiletools-doesnt-cache-result-of-workload-if-type-unstable/102891/5 "2023-08-17T19:11:39Z")

</div>

Thanks for the info (and for your work on PrecompileTools and other tooling packages, which have been a godsend!)

Unfortunately, this proves my MWE isn’t that at all. In my real case, I am getting much more precompilation, involving other libraries like StaticArrays, and which is taking a nontrivial amount of time overall. I thought I had identified the root cause, but I guess I have to look a bit deeper.

I’m marking your answer as the solution, but it’s quite likely I’ll open another issue along similar lines if I can identify another suspicious culprit.

---

<div class="post-metadata">

### Author: ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)
#### Post date: [August 17, 2023, 7:43pm UTC](https://discourse.julialang.org/t/precompiletools-doesnt-cache-result-of-workload-if-type-unstable/102891/6 "2023-08-17T19:43:50Z")

</div>

Come to think of it, do you know why type annotating the value with `::Float64` would make a difference?

---

<div class="post-metadata">

### Author: ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)
#### Post date: [August 17, 2023, 9:07pm UTC](https://discourse.julialang.org/t/precompiletools-doesnt-cache-result-of-workload-if-type-unstable/102891/7 "2023-08-17T21:07:14Z")

</div>

Here’s a likely explanation:

- `>(::Float64, ::Int64)` is known to be inlinable
- Thus we exclude caching a “standalone” version in the sysimage; every inferrable consumer that will need it already has it inlined into the compiled code
- Without the `::Float64` annotation, it can’t be inlined into `foo` because type-inference can’t predict _which_ specialization of `>` will be needed
- Thus without the `::Float64` annotation, the cached version of `foo()` does _not_ inline `>(::Float64, ::Int64)`, and hence it needs to be compiled as a stand-alone function (since it’s among the few that we exclude from the cached sysimage).
- Once you annotate it, inference knows that this is what you’ll be calling, and inlines it. Hence you don’t need to recompile it.

---

<div class="post-metadata">

### Author: ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)
#### Post date: [August 19, 2023, 7:04pm UTC](https://discourse.julialang.org/t/precompiletools-doesnt-cache-result-of-workload-if-type-unstable/102891/8 "2023-08-19T19:04:19Z")

</div>

Update for posterity, the real situation seems to have been resolved with a more representative precompile workload. The underlying issue seemed to be that one of the Meshes functions relies on dynamic dispatch, and one of those methods wasn’t being precompiled.
