]> git.proxmox.com Git - rustc.git/blob - compiler/rustc_query_impl/src/stats.rs
New upstream version 1.57.0+dfsg1
[rustc.git] / compiler / rustc_query_impl / src / stats.rs
1 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
2 use rustc_middle::ty::query::query_storage;
3 use rustc_middle::ty::TyCtxt;
4 use rustc_query_system::query::{QueryCache, QueryCacheStore};
5
6 use std::any::type_name;
7 use std::mem;
8
9 trait KeyStats {
10 fn key_stats(&self, stats: &mut QueryStats);
11 }
12
13 impl<T> KeyStats for T {
14 default fn key_stats(&self, _: &mut QueryStats) {}
15 }
16
17 impl KeyStats for DefId {
18 fn key_stats(&self, stats: &mut QueryStats) {
19 if self.krate == LOCAL_CRATE {
20 stats.local_def_id_keys = Some(stats.local_def_id_keys.unwrap_or(0) + 1);
21 }
22 }
23 }
24
25 #[derive(Clone)]
26 struct QueryStats {
27 name: &'static str,
28 key_size: usize,
29 key_type: &'static str,
30 value_size: usize,
31 value_type: &'static str,
32 entry_count: usize,
33 local_def_id_keys: Option<usize>,
34 }
35
36 fn stats<C>(name: &'static str, map: &QueryCacheStore<C>) -> QueryStats
37 where
38 C: QueryCache,
39 {
40 let mut stats = QueryStats {
41 name,
42 key_size: mem::size_of::<C::Key>(),
43 key_type: type_name::<C::Key>(),
44 value_size: mem::size_of::<C::Value>(),
45 value_type: type_name::<C::Value>(),
46 entry_count: 0,
47 local_def_id_keys: None,
48 };
49 map.iter_results(&mut |key, _, _| {
50 stats.entry_count += 1;
51 key.key_stats(&mut stats)
52 });
53 stats
54 }
55
56 pub fn print_stats(tcx: TyCtxt<'_>) {
57 let queries = query_stats(tcx);
58
59 let mut query_key_sizes = queries.clone();
60 query_key_sizes.sort_by_key(|q| q.key_size);
61 eprintln!("\nLarge query keys:");
62 for q in query_key_sizes.iter().rev().filter(|q| q.key_size > 8) {
63 eprintln!(" {} - {} x {} - {}", q.name, q.key_size, q.entry_count, q.key_type);
64 }
65
66 let mut query_value_sizes = queries.clone();
67 query_value_sizes.sort_by_key(|q| q.value_size);
68 eprintln!("\nLarge query values:");
69 for q in query_value_sizes.iter().rev().filter(|q| q.value_size > 8) {
70 eprintln!(" {} - {} x {} - {}", q.name, q.value_size, q.entry_count, q.value_type);
71 }
72
73 let mut query_value_count = queries.clone();
74 query_value_count.sort_by_key(|q| q.entry_count);
75 eprintln!("\nQuery value count:");
76 for q in query_value_count.iter().rev() {
77 eprintln!(" {} - {}", q.name, q.entry_count);
78 }
79
80 let mut def_id_density: Vec<_> =
81 queries.iter().filter(|q| q.local_def_id_keys.is_some()).collect();
82 def_id_density.sort_by_key(|q| q.local_def_id_keys.unwrap());
83 eprintln!("\nLocal DefId density:");
84 let total = tcx.resolutions(()).definitions.def_index_count() as f64;
85 for q in def_id_density.iter().rev() {
86 let local = q.local_def_id_keys.unwrap();
87 eprintln!(" {} - {} = ({}%)", q.name, local, (local as f64 * 100.0) / total);
88 }
89 }
90
91 macro_rules! print_stats {
92 (<$tcx:tt>
93 $($(#[$attr:meta])* [$($modifiers:tt)*] fn $name:ident($K:ty) -> $V:ty,)*
94 ) => {
95 fn query_stats(tcx: TyCtxt<'_>) -> Vec<QueryStats> {
96 let mut queries = Vec::new();
97
98 $(
99 queries.push(stats::<
100 query_storage::$name<'_>,
101 >(
102 stringify!($name),
103 &tcx.query_caches.$name,
104 ));
105 )*
106
107 queries
108 }
109 }
110 }
111
112 rustc_query_append! { [print_stats!][<'tcx>] }