]>
Commit | Line | Data |
---|---|---|
74b04a01 XL |
1 | use crate::ty::query::queries; |
2 | use crate::ty::TyCtxt; | |
3 | use rustc_hir::def_id::{DefId, LOCAL_CRATE}; | |
29967ef6 | 4 | use rustc_query_system::query::{QueryAccessors, QueryCache, QueryContext, QueryState}; |
74b04a01 XL |
5 | |
6 | use std::any::type_name; | |
29967ef6 | 7 | use std::hash::Hash; |
74b04a01 XL |
8 | use std::mem; |
9 | #[cfg(debug_assertions)] | |
10 | use std::sync::atomic::Ordering; | |
11 | ||
12 | trait KeyStats { | |
13 | fn key_stats(&self, stats: &mut QueryStats); | |
14 | } | |
15 | ||
16 | impl<T> KeyStats for T { | |
17 | default fn key_stats(&self, _: &mut QueryStats) {} | |
18 | } | |
19 | ||
20 | impl KeyStats for DefId { | |
21 | fn key_stats(&self, stats: &mut QueryStats) { | |
22 | if self.krate == LOCAL_CRATE { | |
23 | stats.local_def_id_keys = Some(stats.local_def_id_keys.unwrap_or(0) + 1); | |
24 | } | |
25 | } | |
26 | } | |
27 | ||
28 | #[derive(Clone)] | |
29 | struct QueryStats { | |
30 | name: &'static str, | |
31 | cache_hits: usize, | |
32 | key_size: usize, | |
33 | key_type: &'static str, | |
34 | value_size: usize, | |
35 | value_type: &'static str, | |
36 | entry_count: usize, | |
37 | local_def_id_keys: Option<usize>, | |
38 | } | |
39 | ||
29967ef6 XL |
40 | fn stats<D, Q, C>(name: &'static str, map: &QueryState<D, Q, C>) -> QueryStats |
41 | where | |
42 | D: Copy + Clone + Eq + Hash, | |
43 | Q: Clone, | |
44 | C: QueryCache, | |
45 | { | |
74b04a01 XL |
46 | let mut stats = QueryStats { |
47 | name, | |
48 | #[cfg(debug_assertions)] | |
49 | cache_hits: map.cache_hits.load(Ordering::Relaxed), | |
50 | #[cfg(not(debug_assertions))] | |
51 | cache_hits: 0, | |
ba9703b0 XL |
52 | key_size: mem::size_of::<C::Key>(), |
53 | key_type: type_name::<C::Key>(), | |
54 | value_size: mem::size_of::<C::Value>(), | |
55 | value_type: type_name::<C::Value>(), | |
74b04a01 XL |
56 | entry_count: map.iter_results(|results| results.count()), |
57 | local_def_id_keys: None, | |
58 | }; | |
59 | map.iter_results(|results| { | |
60 | for (key, _, _) in results { | |
61 | key.key_stats(&mut stats) | |
62 | } | |
63 | }); | |
64 | stats | |
65 | } | |
66 | ||
67 | pub fn print_stats(tcx: TyCtxt<'_>) { | |
68 | let queries = query_stats(tcx); | |
69 | ||
70 | if cfg!(debug_assertions) { | |
71 | let hits: usize = queries.iter().map(|s| s.cache_hits).sum(); | |
72 | let results: usize = queries.iter().map(|s| s.entry_count).sum(); | |
73 | println!("\nQuery cache hit rate: {}", hits as f64 / (hits + results) as f64); | |
74 | } | |
75 | ||
76 | let mut query_key_sizes = queries.clone(); | |
77 | query_key_sizes.sort_by_key(|q| q.key_size); | |
78 | println!("\nLarge query keys:"); | |
79 | for q in query_key_sizes.iter().rev().filter(|q| q.key_size > 8) { | |
80 | println!(" {} - {} x {} - {}", q.name, q.key_size, q.entry_count, q.key_type); | |
81 | } | |
82 | ||
83 | let mut query_value_sizes = queries.clone(); | |
84 | query_value_sizes.sort_by_key(|q| q.value_size); | |
85 | println!("\nLarge query values:"); | |
86 | for q in query_value_sizes.iter().rev().filter(|q| q.value_size > 8) { | |
87 | println!(" {} - {} x {} - {}", q.name, q.value_size, q.entry_count, q.value_type); | |
88 | } | |
89 | ||
90 | if cfg!(debug_assertions) { | |
91 | let mut query_cache_hits = queries.clone(); | |
92 | query_cache_hits.sort_by_key(|q| q.cache_hits); | |
93 | println!("\nQuery cache hits:"); | |
94 | for q in query_cache_hits.iter().rev() { | |
95 | println!( | |
96 | " {} - {} ({}%)", | |
97 | q.name, | |
98 | q.cache_hits, | |
99 | q.cache_hits as f64 / (q.cache_hits + q.entry_count) as f64 | |
100 | ); | |
101 | } | |
102 | } | |
103 | ||
104 | let mut query_value_count = queries.clone(); | |
105 | query_value_count.sort_by_key(|q| q.entry_count); | |
106 | println!("\nQuery value count:"); | |
107 | for q in query_value_count.iter().rev() { | |
108 | println!(" {} - {}", q.name, q.entry_count); | |
109 | } | |
110 | ||
111 | let mut def_id_density: Vec<_> = | |
112 | queries.iter().filter(|q| q.local_def_id_keys.is_some()).collect(); | |
113 | def_id_density.sort_by_key(|q| q.local_def_id_keys.unwrap()); | |
114 | println!("\nLocal DefId density:"); | |
115 | let total = tcx.hir().definitions().def_index_count() as f64; | |
116 | for q in def_id_density.iter().rev() { | |
117 | let local = q.local_def_id_keys.unwrap(); | |
118 | println!(" {} - {} = ({}%)", q.name, local, (local as f64 * 100.0) / total); | |
119 | } | |
120 | } | |
121 | ||
122 | macro_rules! print_stats { | |
29967ef6 XL |
123 | (<$tcx:tt> |
124 | $($(#[$attr:meta])* [$($modifiers:tt)*] fn $name:ident($K:ty) -> $V:ty,)* | |
125 | ) => { | |
74b04a01 XL |
126 | fn query_stats(tcx: TyCtxt<'_>) -> Vec<QueryStats> { |
127 | let mut queries = Vec::new(); | |
128 | ||
29967ef6 | 129 | $( |
ba9703b0 | 130 | queries.push(stats::< |
29967ef6 XL |
131 | crate::dep_graph::DepKind, |
132 | <TyCtxt<'_> as QueryContext>::Query, | |
ba9703b0 XL |
133 | <queries::$name<'_> as QueryAccessors<TyCtxt<'_>>>::Cache, |
134 | >( | |
74b04a01 XL |
135 | stringify!($name), |
136 | &tcx.queries.$name, | |
137 | )); | |
29967ef6 | 138 | )* |
74b04a01 XL |
139 | |
140 | queries | |
141 | } | |
142 | } | |
143 | } | |
144 | ||
145 | rustc_query_append! { [print_stats!][<'tcx>] } |