]> git.proxmox.com Git - rustc.git/blame - src/librustc/ty/query/stats.rs
New upstream version 1.43.0+dfsg1
[rustc.git] / src / librustc / ty / query / stats.rs
CommitLineData
74b04a01
XL
1use crate::ty::query::config::QueryAccessors;
2use crate::ty::query::plumbing::QueryState;
3use crate::ty::query::queries;
4use crate::ty::TyCtxt;
5use rustc_hir::def_id::{DefId, LOCAL_CRATE};
6
7use std::any::type_name;
8use std::mem;
9#[cfg(debug_assertions)]
10use std::sync::atomic::Ordering;
11
12trait KeyStats {
13 fn key_stats(&self, stats: &mut QueryStats);
14}
15
16impl<T> KeyStats for T {
17 default fn key_stats(&self, _: &mut QueryStats) {}
18}
19
20impl 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)]
29struct 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
40fn stats<'tcx, Q: QueryAccessors<'tcx>>(
41 name: &'static str,
42 map: &QueryState<'tcx, Q>,
43) -> QueryStats {
44 let mut stats = QueryStats {
45 name,
46 #[cfg(debug_assertions)]
47 cache_hits: map.cache_hits.load(Ordering::Relaxed),
48 #[cfg(not(debug_assertions))]
49 cache_hits: 0,
50 key_size: mem::size_of::<Q::Key>(),
51 key_type: type_name::<Q::Key>(),
52 value_size: mem::size_of::<Q::Value>(),
53 value_type: type_name::<Q::Value>(),
54 entry_count: map.iter_results(|results| results.count()),
55 local_def_id_keys: None,
56 };
57 map.iter_results(|results| {
58 for (key, _, _) in results {
59 key.key_stats(&mut stats)
60 }
61 });
62 stats
63}
64
65pub fn print_stats(tcx: TyCtxt<'_>) {
66 let queries = query_stats(tcx);
67
68 if cfg!(debug_assertions) {
69 let hits: usize = queries.iter().map(|s| s.cache_hits).sum();
70 let results: usize = queries.iter().map(|s| s.entry_count).sum();
71 println!("\nQuery cache hit rate: {}", hits as f64 / (hits + results) as f64);
72 }
73
74 let mut query_key_sizes = queries.clone();
75 query_key_sizes.sort_by_key(|q| q.key_size);
76 println!("\nLarge query keys:");
77 for q in query_key_sizes.iter().rev().filter(|q| q.key_size > 8) {
78 println!(" {} - {} x {} - {}", q.name, q.key_size, q.entry_count, q.key_type);
79 }
80
81 let mut query_value_sizes = queries.clone();
82 query_value_sizes.sort_by_key(|q| q.value_size);
83 println!("\nLarge query values:");
84 for q in query_value_sizes.iter().rev().filter(|q| q.value_size > 8) {
85 println!(" {} - {} x {} - {}", q.name, q.value_size, q.entry_count, q.value_type);
86 }
87
88 if cfg!(debug_assertions) {
89 let mut query_cache_hits = queries.clone();
90 query_cache_hits.sort_by_key(|q| q.cache_hits);
91 println!("\nQuery cache hits:");
92 for q in query_cache_hits.iter().rev() {
93 println!(
94 " {} - {} ({}%)",
95 q.name,
96 q.cache_hits,
97 q.cache_hits as f64 / (q.cache_hits + q.entry_count) as f64
98 );
99 }
100 }
101
102 let mut query_value_count = queries.clone();
103 query_value_count.sort_by_key(|q| q.entry_count);
104 println!("\nQuery value count:");
105 for q in query_value_count.iter().rev() {
106 println!(" {} - {}", q.name, q.entry_count);
107 }
108
109 let mut def_id_density: Vec<_> =
110 queries.iter().filter(|q| q.local_def_id_keys.is_some()).collect();
111 def_id_density.sort_by_key(|q| q.local_def_id_keys.unwrap());
112 println!("\nLocal DefId density:");
113 let total = tcx.hir().definitions().def_index_count() as f64;
114 for q in def_id_density.iter().rev() {
115 let local = q.local_def_id_keys.unwrap();
116 println!(" {} - {} = ({}%)", q.name, local, (local as f64 * 100.0) / total);
117 }
118}
119
120macro_rules! print_stats {
121 (<$tcx:tt> $($category:tt {
122 $($(#[$attr:meta])* [$($modifiers:tt)*] fn $name:ident: $node:ident($K:ty) -> $V:ty,)*
123 },)*) => {
124 fn query_stats(tcx: TyCtxt<'_>) -> Vec<QueryStats> {
125 let mut queries = Vec::new();
126
127 $($(
128 queries.push(stats::<queries::$name<'_>>(
129 stringify!($name),
130 &tcx.queries.$name,
131 ));
132 )*)*
133
134 queries
135 }
136 }
137}
138
139rustc_query_append! { [print_stats!][<'tcx>] }