Skip to content

Merge query cache and query state#156632

Draft
zetanumbers wants to merge 9 commits into
rust-lang:mainfrom
zetanumbers:query_cache_entry
Draft

Merge query cache and query state#156632
zetanumbers wants to merge 9 commits into
rust-lang:mainfrom
zetanumbers:query_cache_entry

Conversation

@zetanumbers
Copy link
Copy Markdown
Contributor

@zetanumbers zetanumbers commented May 16, 2026

So basically we have query cache and query state separate "hash" tables. Cache tracks completed queries while state tracks unfinished queries. Thus we are required to a double check lookup while updating one of them like in try_execute_query and we do multiple hash table lookups while executing a query since cache/state entry might have moved due to rehashing. This PR merges query cache with query state and stores query cache entries in an arena for its stable memory location.

However my manually written slop code currently breaks query cycle detection, but I know how to fix it.

More details in #t-compiler/query-system > Merging query cache and query state

@rustbot rustbot added A-query-system Area: The rustc query system (https://rustc-dev-guide.rust-lang.org/query.html) S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels May 16, 2026
@zetanumbers
Copy link
Copy Markdown
Contributor Author

And there're the benchmark results for 4 threads on my MacBook Pro M1 Pro:

BenchmarkBeforeAfter
TimeTime%
🟣 regex:check0.2070s0.2031s💚 -1.90%
🟣 regex:check:initial0.2437s0.2430s -0.28%
🟣 regex:check:unchanged0.1195s0.1192s -0.25%
🟣 syn:check0.3599s0.3546s💚 -1.48%
🟣 syn:check:initial0.4273s0.4204s💚 -1.63%
🟣 syn:check:unchanged0.2503s0.2473s💚 -1.21%
🟣 clap:check0.3343s0.3274s💚 -2.07%
🟣 clap:check:initial0.3885s0.3804s💚 -2.10%
🟣 clap:check:unchanged0.1589s0.1582s -0.46%
🟣 hyper:check0.0757s0.0731s💚 -3.42%
🟣 hyper:check:initial0.0913s0.0882s💚 -3.44%
🟣 hyper:check:unchanged0.0545s0.0548s 0.53%
Total2.7109s2.6694s💚 -1.53%
Summary1.0000s0.9852s💚 -1.48%

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@zetanumbers
Copy link
Copy Markdown
Contributor Author

Can't get the parallel frontend cycle errors quite right as cycle breaking code cannot find any. This seems to only happen on a second break_query_cycle call tho. So I think maybe I didn't account for that somehow when thinking about order of operations or smth.

@zetanumbers
Copy link
Copy Markdown
Contributor Author

Ah, and single-threaded cycle recovery haven't yet been put back too.

@petrochenkov
Copy link
Copy Markdown
Contributor

@bors try @rust-timer queue

@rust-timer

This comment has been minimized.

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label May 22, 2026
@rust-bors

This comment has been minimized.

rust-bors Bot pushed a commit that referenced this pull request May 22, 2026
@rust-log-analyzer

This comment has been minimized.

@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors Bot commented May 22, 2026

☀️ Try build successful (CI)
Build commit: 0ac810c (0ac810c5d67b1974c32e84e3ae9a74710b55ad5c, parent: 3bf5c6d99bc8a0c0d5b2f69826ed4f6d256a0a21)

@rust-timer

This comment has been minimized.

@rust-timer
Copy link
Copy Markdown
Collaborator

Finished benchmarking commit (0ac810c): comparison URL.

Overall result: ❌✅ regressions and improvements - please read:

Benchmarking means the PR may be perf-sensitive. It's automatically marked not fit for rolling up. Overriding is possible but disadvised: it risks changing compiler perf.

Next, please: If you can, justify the regressions found in this try perf run in writing along with @rustbot label: +perf-regression-triaged. If not, fix the regressions and do another perf run. Neutral or positive results will clear the label automatically.

@bors rollup=never
@rustbot label: -S-waiting-on-perf +perf-regression

Instruction count

Our most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.

mean range count
Regressions ❌
(primary)
2.1% [0.2%, 21.6%] 237
Regressions ❌
(secondary)
3.9% [0.2%, 23.4%] 280
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-0.6% [-1.0%, -0.2%] 13
All ❌✅ (primary) 2.1% [0.2%, 21.6%] 237

Max RSS (memory usage)

Results (primary 0.8%, secondary 2.5%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
3.0% [1.0%, 6.2%] 9
Regressions ❌
(secondary)
4.1% [0.8%, 10.0%] 33
Improvements ✅
(primary)
-1.8% [-3.1%, -0.9%] 8
Improvements ✅
(secondary)
-5.0% [-10.2%, -0.8%] 7
All ❌✅ (primary) 0.8% [-3.1%, 6.2%] 17

Cycles

Results (primary 5.6%, secondary 5.9%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
5.6% [2.0%, 32.1%] 123
Regressions ❌
(secondary)
5.9% [1.8%, 23.9%] 179
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) 5.6% [2.0%, 32.1%] 123

Binary size

Results (primary 0.1%, secondary 0.1%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
0.1% [0.0%, 0.1%] 74
Regressions ❌
(secondary)
0.1% [0.0%, 0.1%] 25
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) 0.1% [0.0%, 0.1%] 74

Bootstrap: 513.065s -> 530.367s (3.37%)
Artifact size: 400.58 MiB -> 404.66 MiB (1.02%)

@rustbot rustbot added perf-regression Performance regression. and removed S-waiting-on-perf Status: Waiting on a perf run to be completed. labels May 22, 2026
@rust-log-analyzer
Copy link
Copy Markdown
Collaborator

The job aarch64-gnu-llvm-21-2 failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)
   Compiling rustc_data_structures v0.0.0 (/checkout/compiler/rustc_data_structures)
error[E0308]: mismatched types
   --> compiler/rustc_data_structures/src/vec_cache/tests.rs:44:30
    |
 44 |         assert!(cache.lookup(&key).is_none());
    |                       ------ ^^^^ expected `u32`, found `&u32`
    |                       |
    |                       arguments to this method are incorrect
    |
note: method defined here
   --> compiler/rustc_data_structures/src/vec_cache.rs:191:12
    |
191 |     pub fn lookup(&self, key: K) -> &CacheEntry<V> {
    |            ^^^^^^        ------
help: consider removing the borrow
    |
 44 -         assert!(cache.lookup(&key).is_none());
 44 +         assert!(cache.lookup(key).is_none());
    |

error[E0599]: no method named `is_none` found for reference `&CacheEntry<u32>` in the current scope
  --> compiler/rustc_data_structures/src/vec_cache/tests.rs:44:36
   |
44 |         assert!(cache.lookup(&key).is_none());
   |                                    ^^^^^^^ method not found in `&CacheEntry<u32>`

error[E0599]: no method named `complete` found for struct `vec_cache::VecCache<K, V, I>` in the current scope
   --> compiler/rustc_data_structures/src/vec_cache/tests.rs:51:11
    |
 51 |     cache.complete(0, 1, 2);
    |           ^^^^^^^^ method not found in `vec_cache::VecCache<u32, u32, u32>`
    |
   ::: compiler/rustc_data_structures/src/vec_cache.rs:138:1
    |
138 | pub struct VecCache<K: Idx, V, I> {
    | --------------------------------- method `complete` not found for this struct

error[E0308]: mismatched types
   --> compiler/rustc_data_structures/src/vec_cache/tests.rs:52:29
    |
 52 |     assert_eq!(cache.lookup(&0), Some((1, 2)));
    |                      ------ ^^ expected `u32`, found `&{integer}`
    |                      |
    |                      arguments to this method are incorrect
    |
note: method defined here
   --> compiler/rustc_data_structures/src/vec_cache.rs:191:12
    |
191 |     pub fn lookup(&self, key: K) -> &CacheEntry<V> {
    |            ^^^^^^        ------
help: consider removing the borrow
    |
 52 -     assert_eq!(cache.lookup(&0), Some((1, 2)));
 52 +     assert_eq!(cache.lookup(0), Some((1, 2)));
    |

error[E0369]: binary operation `==` cannot be applied to type `&CacheEntry<u32>`
  --> library/core/src/macros/mod.rs:46:32
   |
42 | macro_rules! assert_eq {
   | ---------------------- in this expansion of `assert_eq!`
...
46 |                 if !(*left_val == *right_val) {
   |                      --------- ^^ ---------- Option<({integer}, {integer})>
   |                      |
   |                      &CacheEntry<u32>
   |
  ::: compiler/rustc_data_structures/src/vec_cache/tests.rs:52:5
   |
52 |     assert_eq!(cache.lookup(&0), Some((1, 2)));
   |     ------------------------------------------ in this macro invocation

error[E0277]: `CacheEntry<u32>` doesn't implement `std::fmt::Debug`
  --> library/core/src/macros/mod.rs:51:61
   |
42 | macro_rules! assert_eq {
   | ---------------------- in this expansion of `assert_eq!`
...
51 |                     $crate::panicking::assert_failed(kind, &*left_val, &*right_val, $crate::option::Option::None);
   |                                                             ^^^^^^^^^ unsatisfied trait bound
   |
  ::: compiler/rustc_data_structures/src/vec_cache/tests.rs:52:5
   |
52 |     assert_eq!(cache.lookup(&0), Some((1, 2)));
   |     ------------------------------------------ in this macro invocation
   |
help: the trait `std::fmt::Debug` is not implemented for `CacheEntry<u32>`
  --> compiler/rustc_data_structures/src/cache_entry.rs:82:1
   |
82 | pub struct CacheEntry<V> {
   | ^^^^^^^^^^^^^^^^^^^^^^^^
   = note: add `#[derive(Debug)]` to `CacheEntry<u32>` or manually `impl std::fmt::Debug for CacheEntry<u32>`

error[E0599]: no method named `complete` found for struct `vec_cache::VecCache<K, V, I>` in the current scope
   --> compiler/rustc_data_structures/src/vec_cache/tests.rs:73:15
    |
 73 |         cache.complete(key, shift, key);
    |               ^^^^^^^^ method not found in `vec_cache::VecCache<u32, u8, u32>`
    |
   ::: compiler/rustc_data_structures/src/vec_cache.rs:138:1
    |
138 | pub struct VecCache<K: Idx, V, I> {
    | --------------------------------- method `complete` not found for this struct

error[E0308]: mismatched types
   --> compiler/rustc_data_structures/src/vec_cache/tests.rs:74:33
    |
 74 |         assert_eq!(cache.lookup(&key), Some((shift, key)));
    |                          ------ ^^^^ expected `u32`, found `&u32`
    |                          |
    |                          arguments to this method are incorrect
    |
note: method defined here
   --> compiler/rustc_data_structures/src/vec_cache.rs:191:12
    |
191 |     pub fn lookup(&self, key: K) -> &CacheEntry<V> {
    |            ^^^^^^        ------
help: consider removing the borrow
    |
 74 -         assert_eq!(cache.lookup(&key), Some((shift, key)));
 74 +         assert_eq!(cache.lookup(key), Some((shift, key)));
    |

error[E0369]: binary operation `==` cannot be applied to type `&CacheEntry<u8>`
  --> library/core/src/macros/mod.rs:46:32
   |
42 | macro_rules! assert_eq {
   | ---------------------- in this expansion of `assert_eq!`
...
46 |                 if !(*left_val == *right_val) {
   |                      --------- ^^ ---------- Option<({integer}, u32)>
   |                      |
   |                      &CacheEntry<u8>
   |
  ::: compiler/rustc_data_structures/src/vec_cache/tests.rs:74:9
   |
74 |         assert_eq!(cache.lookup(&key), Some((shift, key)));
   |         -------------------------------------------------- in this macro invocation

error[E0277]: `CacheEntry<u8>` doesn't implement `std::fmt::Debug`
  --> library/core/src/macros/mod.rs:51:61
   |
42 | macro_rules! assert_eq {
   | ---------------------- in this expansion of `assert_eq!`
...
51 |                     $crate::panicking::assert_failed(kind, &*left_val, &*right_val, $crate::option::Option::None);
   |                                                             ^^^^^^^^^ unsatisfied trait bound
   |
  ::: compiler/rustc_data_structures/src/vec_cache/tests.rs:74:9
   |
74 |         assert_eq!(cache.lookup(&key), Some((shift, key)));
   |         -------------------------------------------------- in this macro invocation
   |
help: the trait `std::fmt::Debug` is not implemented for `CacheEntry<u8>`
  --> compiler/rustc_data_structures/src/cache_entry.rs:82:1
   |
82 | pub struct CacheEntry<V> {
   | ^^^^^^^^^^^^^^^^^^^^^^^^
   = note: add `#[derive(Debug)]` to `CacheEntry<u8>` or manually `impl std::fmt::Debug for CacheEntry<u8>`

error[E0599]: no method named `complete` found for reference `&vec_cache::VecCache<u32, u32, u32>` in the current scope
  --> compiler/rustc_data_structures/src/vec_cache/tests.rs:85:23
   |
85 |                 cache.complete(idx, idx, idx);
   |                       ^^^^^^^^ method not found in `&vec_cache::VecCache<u32, u32, u32>`

error[E0308]: mismatched types
   --> compiler/rustc_data_structures/src/vec_cache/tests.rs:91:33
    |
 91 |         assert_eq!(cache.lookup(&idx), Some((idx, idx)));
    |                          ------ ^^^^ expected `u32`, found `&{integer}`
    |                          |
    |                          arguments to this method are incorrect
    |
note: method defined here
   --> compiler/rustc_data_structures/src/vec_cache.rs:191:12
    |
191 |     pub fn lookup(&self, key: K) -> &CacheEntry<V> {
    |            ^^^^^^        ------
help: consider removing the borrow
    |
 91 -         assert_eq!(cache.lookup(&idx), Some((idx, idx)));
 91 +         assert_eq!(cache.lookup(idx), Some((idx, idx)));
    |

error[E0369]: binary operation `==` cannot be applied to type `&CacheEntry<u32>`
  --> library/core/src/macros/mod.rs:46:32
   |
42 | macro_rules! assert_eq {
   | ---------------------- in this expansion of `assert_eq!`
...
46 |                 if !(*left_val == *right_val) {
   |                      --------- ^^ ---------- Option<({integer}, {integer})>
   |                      |
   |                      &CacheEntry<u32>
   |
  ::: compiler/rustc_data_structures/src/vec_cache/tests.rs:91:9
   |
91 |         assert_eq!(cache.lookup(&idx), Some((idx, idx)));
   |         ------------------------------------------------ in this macro invocation

error[E0277]: `CacheEntry<u32>` doesn't implement `std::fmt::Debug`
  --> library/core/src/macros/mod.rs:51:61
   |
42 | macro_rules! assert_eq {
   | ---------------------- in this expansion of `assert_eq!`
...
51 |                     $crate::panicking::assert_failed(kind, &*left_val, &*right_val, $crate::option::Option::None);
   |                                                             ^^^^^^^^^ unsatisfied trait bound
   |
  ::: compiler/rustc_data_structures/src/vec_cache/tests.rs:91:9
   |
91 |         assert_eq!(cache.lookup(&idx), Some((idx, idx)));
   |         ------------------------------------------------ in this macro invocation
   |
help: the trait `std::fmt::Debug` is not implemented for `CacheEntry<u32>`
  --> compiler/rustc_data_structures/src/cache_entry.rs:82:1
   |
82 | pub struct CacheEntry<V> {
   | ^^^^^^^^^^^^^^^^^^^^^^^^
   = note: add `#[derive(Debug)]` to `CacheEntry<u32>` or manually `impl std::fmt::Debug for CacheEntry<u32>`

Some errors have detailed explanations: E0277, E0308, E0369, E0599.
For more information about an error, try `rustc --explain E0277`.
[RUSTC-TIMING] rustc_data_structures test:true 3.621
error: could not compile `rustc_data_structures` (lib test) due to 14 previous errors

@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors Bot commented May 30, 2026

☔ The latest upstream changes (presumably #157149) made this pull request unmergeable. Please resolve the merge conflicts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-query-system Area: The rustc query system (https://rustc-dev-guide.rust-lang.org/query.html) perf-regression Performance regression. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants