Skip to content

Commit 8a9fa36

Browse files
committed
Auto merge of rust-lang#84719 - Mark-Simulacrum:reduce-query-impl, r=davidtwco
Move iter_results to dyn FnMut rather than a generic This means that we're no longer generating the iteration/locking code for each invocation site of iter_results, rather just once per query (roughly), which seems much better: this is a 15% win in instruction counts when compiling the rustc_query_impl crate. The code where this is used also is pretty cold, I suspect; the old solution didn't fully monomorphize either.
2 parents 4ae0a8e + a1d7367 commit 8a9fa36

File tree

5 files changed

+55
-49
lines changed

5 files changed

+55
-49
lines changed

compiler/rustc_middle/src/ty/query/on_disk_cache.rs

+21-14
Original file line numberDiff line numberDiff line change
@@ -1185,20 +1185,27 @@ where
11851185

11861186
assert!(Q::query_state(tcx).all_inactive());
11871187
let cache = Q::query_cache(tcx);
1188-
cache.iter_results(|results| {
1189-
for (key, value, dep_node) in results {
1190-
if Q::cache_on_disk(tcx, &key, Some(value)) {
1191-
let dep_node = SerializedDepNodeIndex::new(dep_node.index());
1192-
1193-
// Record position of the cache entry.
1194-
query_result_index
1195-
.push((dep_node, AbsoluteBytePos::new(encoder.encoder.position())));
1196-
1197-
// Encode the type check tables with the `SerializedDepNodeIndex`
1198-
// as tag.
1199-
encoder.encode_tagged(dep_node, value)?;
1188+
let mut res = Ok(());
1189+
cache.iter_results(&mut |key, value, dep_node| {
1190+
if res.is_err() {
1191+
return;
1192+
}
1193+
if Q::cache_on_disk(tcx, &key, Some(value)) {
1194+
let dep_node = SerializedDepNodeIndex::new(dep_node.index());
1195+
1196+
// Record position of the cache entry.
1197+
query_result_index.push((dep_node, AbsoluteBytePos::new(encoder.encoder.position())));
1198+
1199+
// Encode the type check tables with the `SerializedDepNodeIndex`
1200+
// as tag.
1201+
match encoder.encode_tagged(dep_node, value) {
1202+
Ok(()) => {}
1203+
Err(e) => {
1204+
res = Err(e);
1205+
}
12001206
}
12011207
}
1202-
Ok(())
1203-
})
1208+
});
1209+
1210+
res
12041211
}

compiler/rustc_query_impl/src/profiling_support.rs

+10-9
Original file line numberDiff line numberDiff line change
@@ -250,8 +250,8 @@ fn alloc_self_profile_query_strings_for_query_cache<'tcx, C>(
250250
// need to invoke queries itself, we cannot keep the query caches
251251
// locked while doing so. Instead we copy out the
252252
// `(query_key, dep_node_index)` pairs and release the lock again.
253-
let query_keys_and_indices: Vec<_> = query_cache
254-
.iter_results(|results| results.map(|(k, _, i)| (k.clone(), i)).collect());
253+
let mut query_keys_and_indices = Vec::new();
254+
query_cache.iter_results(&mut |k, _, i| query_keys_and_indices.push((k.clone(), i)));
255255

256256
// Now actually allocate the strings. If allocating the strings
257257
// generates new entries in the query cache, we'll miss them but
@@ -275,14 +275,15 @@ fn alloc_self_profile_query_strings_for_query_cache<'tcx, C>(
275275
let query_name = profiler.get_or_alloc_cached_string(query_name);
276276
let event_id = event_id_builder.from_label(query_name).to_string_id();
277277

278-
query_cache.iter_results(|results| {
279-
let query_invocation_ids: Vec<_> = results.map(|v| v.2.into()).collect();
280-
281-
profiler.bulk_map_query_invocation_id_to_single_string(
282-
query_invocation_ids.into_iter(),
283-
event_id,
284-
);
278+
let mut query_invocation_ids = Vec::new();
279+
query_cache.iter_results(&mut |_, _, i| {
280+
query_invocation_ids.push(i.into());
285281
});
282+
283+
profiler.bulk_map_query_invocation_id_to_single_string(
284+
query_invocation_ids.into_iter(),
285+
event_id,
286+
);
286287
}
287288
});
288289
}

compiler/rustc_query_impl/src/stats.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,12 @@ where
5050
key_type: type_name::<C::Key>(),
5151
value_size: mem::size_of::<C::Value>(),
5252
value_type: type_name::<C::Value>(),
53-
entry_count: map.iter_results(|results| results.count()),
53+
entry_count: 0,
5454
local_def_id_keys: None,
5555
};
56-
map.iter_results(|results| {
57-
for (key, _, _) in results {
58-
key.key_stats(&mut stats)
59-
}
56+
map.iter_results(&mut |key, _, _| {
57+
stats.entry_count += 1;
58+
key.key_stats(&mut stats)
6059
});
6160
stats
6261
}

compiler/rustc_query_system/src/query/caches.rs

+19-15
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,11 @@ pub trait QueryCache: QueryStorage {
4949
index: DepNodeIndex,
5050
) -> Self::Stored;
5151

52-
fn iter<R>(
52+
fn iter(
5353
&self,
5454
shards: &Sharded<Self::Sharded>,
55-
f: impl for<'a> FnOnce(
56-
&'a mut dyn Iterator<Item = (&'a Self::Key, &'a Self::Value, DepNodeIndex)>,
57-
) -> R,
58-
) -> R;
55+
f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex),
56+
);
5957
}
6058

6159
pub struct DefaultCacheSelector;
@@ -124,14 +122,17 @@ where
124122
value
125123
}
126124

127-
fn iter<R>(
125+
fn iter(
128126
&self,
129127
shards: &Sharded<Self::Sharded>,
130-
f: impl for<'a> FnOnce(&'a mut dyn Iterator<Item = (&'a K, &'a V, DepNodeIndex)>) -> R,
131-
) -> R {
128+
f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex),
129+
) {
132130
let shards = shards.lock_shards();
133-
let mut results = shards.iter().flat_map(|shard| shard.iter()).map(|(k, v)| (k, &v.0, v.1));
134-
f(&mut results)
131+
for shard in shards.iter() {
132+
for (k, v) in shard.iter() {
133+
f(k, &v.0, v.1);
134+
}
135+
}
135136
}
136137
}
137138

@@ -207,13 +208,16 @@ where
207208
&value.0
208209
}
209210

210-
fn iter<R>(
211+
fn iter(
211212
&self,
212213
shards: &Sharded<Self::Sharded>,
213-
f: impl for<'a> FnOnce(&'a mut dyn Iterator<Item = (&'a K, &'a V, DepNodeIndex)>) -> R,
214-
) -> R {
214+
f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex),
215+
) {
215216
let shards = shards.lock_shards();
216-
let mut results = shards.iter().flat_map(|shard| shard.iter()).map(|(k, v)| (k, &v.0, v.1));
217-
f(&mut results)
217+
for shard in shards.iter() {
218+
for (k, v) in shard.iter() {
219+
f(k, &v.0, v.1);
220+
}
221+
}
218222
}
219223
}

compiler/rustc_query_system/src/query/plumbing.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,7 @@ impl<C: QueryCache> QueryCacheStore<C> {
7373
(QueryLookup { key_hash, shard }, lock)
7474
}
7575

76-
pub fn iter_results<R>(
77-
&self,
78-
f: impl for<'a> FnOnce(
79-
&'a mut dyn Iterator<Item = (&'a C::Key, &'a C::Value, DepNodeIndex)>,
80-
) -> R,
81-
) -> R {
76+
pub fn iter_results(&self, f: &mut dyn FnMut(&C::Key, &C::Value, DepNodeIndex)) {
8277
self.cache.iter(&self.shards, f)
8378
}
8479
}

0 commit comments

Comments
 (0)