Skip to content

perf: restrict and record option accesses during type class resolution - #14932

Draft
Kha wants to merge 3 commits into
masterfrom
push-pnlkkqrtolzm
Draft

perf: restrict and record option accesses during type class resolution#14932
Kha wants to merge 3 commits into
masterfrom
push-pnlkkqrtolzm

Conversation

@Kha

@Kha Kha commented Aug 26, 2026

Copy link
Copy Markdown
Member

This PR makes type class resolution cache entries depend on the options they observed, as a first prerequisite for more extensive caching.

A query now records every result-relevant option lookup (Lean.getRecordedOption), and an entry is served only while its recorded lookups give the same answers, so options no longer have to invalidate the cache wholesale (nor silently fail to). Options resolved once per query, such as the definitional-equality compatibility flags and the resource limits, are part of the cache key instead.

Acquiring the options directly is forbidden: getOptions panics while Core.Context.recordingDeps is set, so nothing can go unrecorded. Type class resolution is a closed system, so the few readers whose result cannot influence a cached entry acquire them through the new MonadOptions.getOptionsUnrestricted, each carrying its one-line argument (trace and profiler collection, message rendering, diagnostics counters, and limits whose excess throws and is never cached). The marker is scoped to the computation rather than carried by the options value or the environment, both of which outlive the query in contexts captured for later rendering.

@Kha

Kha commented Aug 26, 2026

Copy link
Copy Markdown
Member Author

!bench

@leanprover-radar

leanprover-radar commented Aug 26, 2026

Copy link
Copy Markdown

Benchmark results for e32b54b against b9c9eb9 are in. There are significant results. @Kha

  • 🟥 build exited with code 1
  • 🟥 other exited with code 1

No significant changes detected.

@Kha

Kha commented Aug 26, 2026

Copy link
Copy Markdown
Member Author

!bench

@Kha
Kha force-pushed the push-pnlkkqrtolzm branch from e32b54b to c71b1d3 Compare August 26, 2026 14:10
@leanprover-radar

leanprover-radar commented Aug 26, 2026

Copy link
Copy Markdown

Benchmark results for c71b1d3 against b9c9eb9 are in. There are significant results. @Kha

  • 🟥 build//instructions: +32.7G (+0.28%)

Medium changes (4🟥)

  • 🟥 size/all/.ir//bytes: +2MiB (+0.48%)
  • 🟥 size/all/.olean.private//bytes: +6MiB (+0.42%)
  • 🟥 size/compile/.out//bytes: +15MiB (+0.53%)
  • 🟥 size/libleanshared.so//bytes: +977kiB (+0.43%)

Small changes (190🟥)

  • 🟥 build/module/Init.Data.Array.Basic//instructions: +26.5M (+0.24%)
  • 🟥 build/module/Init.Data.Array.Erase//instructions: +21.9M (+0.31%)
  • 🟥 build/module/Init.Data.Array.Find//instructions: +23.7M (+0.24%)
  • 🟥 build/module/Init.Data.Array.Lemmas//instructions: +156.0M (+0.29%)
  • 🟥 build/module/Init.Data.Array.Lex.Lemmas//instructions: +40.9M (+0.43%)
  • 🟥 build/module/Init.Data.Array.MapIdx//instructions: +23.7M (+0.27%)
  • 🟥 build/module/Init.Data.Array.QSort.Basic//instructions: +36.9M (+0.37%)
  • 🟥 build/module/Init.Data.BitVec.Bitblast//instructions: +134.2M (+0.27%)
  • 🟥 build/module/Init.Data.BitVec.Lemmas//instructions: +341.4M (+0.29%)
  • 🟥 build/module/Init.Data.Int.DivMod.Lemmas//instructions: +122.4M (+0.33%)
  • 🟥 build/module/Init.Data.Iterators.Lemmas.Combinators.FilterMap//instructions: +51.6M (+0.27%)
  • 🟥 build/module/Init.Data.Iterators.Lemmas.Combinators.Monadic.FilterMap//instructions: +118.2M (+0.33%)
  • 🟥 build/module/Init.Data.Iterators.Lemmas.Consumers.Loop//instructions: +32.8M (+0.31%)
  • 🟥 build/module/Init.Data.Iterators.Lemmas.Consumers.Monadic.Loop//instructions: +38.8M (+0.32%)
  • 🟥 build/module/Init.Data.List.Find//instructions: +63.9M (+0.34%)
  • 🟥 build/module/Init.Data.List.Lemmas//instructions: +106.6M (+0.28%)
  • 🟥 build/module/Init.Data.List.MinMaxIdx//instructions: +32.1M (+0.33%)
  • 🟥 build/module/Init.Data.List.ToArray//instructions: +47.6M (+0.27%)
  • 🟥 build/module/Init.Data.Nat.Lemmas//instructions: +86.8M (+0.36%)
  • 🟥 build/module/Init.Data.Range.Polymorphic.IntLemmas//instructions: +108.4M (+0.41%)
  • and 169 more
  • and 1 hidden

Kha and others added 2 commits August 27, 2026 13:45
This PR makes type class resolution cache entries depend on the options they observed: a query records every result-relevant option lookup (`Lean.getRecordedOption`), and an entry is served only while its recorded lookups give the same answers, so options no longer have to invalidate the cache wholesale (nor silently fail to). Options resolved once per query, such as the definitional-equality compatibility flags and the resource limits, are part of the cache key instead.

Acquiring the options plainly is what a running query forbids: `getOptions` panics while `Core.Context.recordingDeps` is set, so nothing can go unrecorded. Type class resolution is a closed system, so the few readers whose result cannot influence a cached entry acquire them through the new `MonadOptions.getOptionsUnrestricted`, each carrying its one-line argument (trace and profiler collection, message rendering, diagnostics counters, and limits whose excess throws and is never cached). The marker is scoped to the computation rather than carried by the options value or the environment, both of which outlive the query in contexts captured for later rendering.

The reachable set was measured rather than estimated: over the full `tests/elab` pile a recording query acquires the options 4.3M times from 17 source sites, all of them either audited unrestricted readers or the cache machinery itself.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This PR speeds up type class resolution by storing the definitional-equality flags and resource limits that partition the resolution cache as unboxed words rather than as pointers to records, so that hashing and comparing a cache key no longer walks thirteen boxed fields on every probe.

`SynthDefEqFlags` becomes a single `UInt32` bitfield with accessors, which the compiler erases to a bare word, and `SynthLimits` is inlined into `SynthInstanceCacheKey` as four `UInt64` fields. The key therefore carries five unboxed scalars instead of two pointers to freshly allocated records, which also removes two allocations per query.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@Kha
Kha force-pushed the push-pnlkkqrtolzm branch from c71b1d3 to 7aa96c2 Compare August 27, 2026 13:55
@Kha

Kha commented Aug 27, 2026

Copy link
Copy Markdown
Member Author

!bench

@leanprover-radar

leanprover-radar commented Aug 27, 2026

Copy link
Copy Markdown

Benchmark results for 7aa96c2 against b9c9eb9 are in. There are significant results. @Kha

  • 🟥 build//instructions: +32.9G (+0.28%)

Medium changes (4🟥)

  • 🟥 size/all/.ir//bytes: +2MiB (+0.48%)
  • 🟥 size/all/.olean.private//bytes: +5MiB (+0.42%)
  • 🟥 size/compile/.out//bytes: +15MiB (+0.53%)
  • 🟥 size/libleanshared.so//bytes: +978kiB (+0.43%)

Small changes (182🟥)

  • 🟥 build/module/Init.Data.Array.Basic//instructions: +26.4M (+0.24%)
  • 🟥 build/module/Init.Data.Array.Find//instructions: +25.6M (+0.26%)
  • 🟥 build/module/Init.Data.Array.Lemmas//instructions: +162.4M (+0.31%)
  • 🟥 build/module/Init.Data.Array.Lex.Lemmas//instructions: +39.9M (+0.42%)
  • 🟥 build/module/Init.Data.Array.MapIdx//instructions: +21.9M (+0.25%)
  • 🟥 build/module/Init.Data.Array.QSort.Basic//instructions: +35.0M (+0.35%)
  • 🟥 build/module/Init.Data.BitVec.Bitblast//instructions: +114.2M (+0.23%)
  • 🟥 build/module/Init.Data.BitVec.Lemmas//instructions: +305.2M (+0.26%)
  • 🟥 build/module/Init.Data.Int.DivMod.Lemmas//instructions: +129.4M (+0.35%)
  • 🟥 build/module/Init.Data.Iterators.Lemmas.Combinators.FilterMap//instructions: +52.2M (+0.27%)
  • 🟥 build/module/Init.Data.Iterators.Lemmas.Combinators.Monadic.FilterMap//instructions: +105.0M (+0.30%)
  • 🟥 build/module/Init.Data.Iterators.Lemmas.Consumers.Loop//instructions: +37.0M (+0.35%)
  • 🟥 build/module/Init.Data.Iterators.Lemmas.Consumers.Monadic.Loop//instructions: +40.2M (+0.33%)
  • 🟥 build/module/Init.Data.List.Find//instructions: +63.7M (+0.34%)
  • 🟥 build/module/Init.Data.List.Lemmas//instructions: +119.9M (+0.31%)
  • 🟥 build/module/Init.Data.List.MinMaxIdx//instructions: +30.6M (+0.32%)
  • 🟥 build/module/Init.Data.List.ToArray//instructions: +50.7M (+0.28%)
  • 🟥 build/module/Init.Data.Nat.Lemmas//instructions: +93.1M (+0.38%)
  • 🟥 build/module/Init.Data.Range.Polymorphic.IntLemmas//instructions: +109.7M (+0.41%)
  • 🟥 build/module/Init.Data.Range.Polymorphic.Lemmas//instructions: +169.8M (+0.39%)
  • and 161 more
  • and 1 hidden

…word

This PR removes a pointer field from `Meta.Context`, which is reconstructed on every `withConfig`/`withTransparency`-style scope, by storing the resolved definitional-equality flags as a sentinel-tagged `UInt32` instead of an `Option`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions github-actions Bot added toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN mathlib4-nightly-available A branch for this PR exists at leanprover-community/mathlib4-nightly-testing:lean-pr-testing-NNNN labels Aug 27, 2026
@mathlib-lean-pr-testing

mathlib-lean-pr-testing Bot commented Aug 27, 2026

Copy link
Copy Markdown

Mathlib CI status (docs):

@leanprover-bot leanprover-bot added the builds-manual CI has verified that the Lean Language Reference builds against this PR label Aug 27, 2026
@leanprover-bot

leanprover-bot commented Aug 27, 2026

Copy link
Copy Markdown
Collaborator

Reference manual CI status:

@Kha

Kha commented Aug 27, 2026

Copy link
Copy Markdown
Member Author

!bench

@leanprover-radar

leanprover-radar commented Aug 27, 2026

Copy link
Copy Markdown

Benchmark results for 3fbd61b against b9c9eb9 are in. There are significant results. @Kha

  • 🟥 build//instructions: +27.7G (+0.24%)

Medium changes (4🟥)

  • 🟥 size/all/.ir//bytes: +2MiB (+0.49%)
  • 🟥 size/all/.olean.private//bytes: +5MiB (+0.42%)
  • 🟥 size/compile/.out//bytes: +14MiB (+0.50%)
  • 🟥 size/libleanshared.so//bytes: +932kiB (+0.41%)

Small changes (145🟥)

  • 🟥 build/module/Init.Data.Array.Lemmas//instructions: +115.3M (+0.22%)
  • 🟥 build/module/Init.Data.Array.Lex.Lemmas//instructions: +30.5M (+0.32%)
  • 🟥 build/module/Init.Data.BitVec.Lemmas//instructions: +258.2M (+0.22%)
  • 🟥 build/module/Init.Data.Int.DivMod.Lemmas//instructions: +103.8M (+0.28%)
  • 🟥 build/module/Init.Data.Iterators.Lemmas.Combinators.FilterMap//instructions: +35.6M (+0.19%)
  • 🟥 build/module/Init.Data.Iterators.Lemmas.Combinators.Monadic.FilterMap//instructions: +77.8M (+0.22%)
  • 🟥 build/module/Init.Data.List.Find//instructions: +49.0M (+0.26%)
  • 🟥 build/module/Init.Data.List.Lemmas//instructions: +73.2M (+0.19%)
  • 🟥 build/module/Init.Data.List.MinMaxIdx//instructions: +26.3M (+0.27%)
  • 🟥 build/module/Init.Data.Nat.Lemmas//instructions: +75.4M (+0.31%)
  • 🟥 build/module/Init.Data.Range.Polymorphic.Lemmas//instructions: +130.0M (+0.30%)
  • 🟥 build/module/Init.Data.Range.Polymorphic.NatLemmas//instructions: +120.2M (+0.36%)
  • 🟥 build/module/Init.Data.Range.Polymorphic.UInt//instructions: +13.3M (+0.31%)
  • 🟥 build/module/Init.Data.SInt.Bitwise//instructions: +30.4M (+0.26%)
  • 🟥 build/module/Init.Data.String.Decode//instructions: +56.7M (+0.23%)
  • 🟥 build/module/Init.Data.UInt.Bitwise//instructions: +57.6M (+0.27%)
  • 🟥 build/module/Lake.DSL.Attributes//instructions: +15.2M (+1.63%)
  • 🟥 build/module/Lake.DSL.Meta//instructions: +26.4M (+0.95%)
  • 🟥 build/module/Lake.Toml.Elab.Expression//instructions: +25.5M (+0.68%)
  • 🟥 build/module/Lean.AddDecl//instructions: +155.2M (+2.76%) (reduced significance based on absolute threshold)
  • and 124 more
  • and 1 hidden

mathlib-nightly-testing Bot pushed a commit to leanprover-community/batteries that referenced this pull request Aug 27, 2026
mathlib-nightly-testing Bot pushed a commit to leanprover-community/mathlib4-nightly-testing that referenced this pull request Aug 27, 2026
leanprover-bot added a commit to leanprover/reference-manual that referenced this pull request Aug 27, 2026
@mathlib-lean-pr-testing mathlib-lean-pr-testing Bot added the builds-mathlib CI has verified that Mathlib builds against this PR label Aug 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

builds-manual CI has verified that the Lean Language Reference builds against this PR builds-mathlib CI has verified that Mathlib builds against this PR mathlib4-nightly-available A branch for this PR exists at leanprover-community/mathlib4-nightly-testing:lean-pr-testing-NNNN toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants