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}
;
6 use std
::any
::type_name
;
8 #[cfg(debug_assertions)]
9 use std
::sync
::atomic
::Ordering
;
12 fn key_stats(&self, stats
: &mut QueryStats
);
15 impl<T
> KeyStats
for T
{
16 default fn key_stats(&self, _
: &mut QueryStats
) {}
19 impl KeyStats
for DefId
{
20 fn key_stats(&self, stats
: &mut QueryStats
) {
21 if self.krate
== LOCAL_CRATE
{
22 stats
.local_def_id_keys
= Some(stats
.local_def_id_keys
.unwrap_or(0) + 1);
32 key_type
: &'
static str,
34 value_type
: &'
static str,
36 local_def_id_keys
: Option
<usize>,
39 fn stats
<C
>(name
: &'
static str, map
: &QueryCacheStore
<C
>) -> QueryStats
43 let mut stats
= QueryStats
{
45 #[cfg(debug_assertions)]
46 cache_hits
: map
.cache_hits
.load(Ordering
::Relaxed
),
47 #[cfg(not(debug_assertions))]
49 key_size
: mem
::size_of
::<C
::Key
>(),
50 key_type
: type_name
::<C
::Key
>(),
51 value_size
: mem
::size_of
::<C
::Value
>(),
52 value_type
: type_name
::<C
::Value
>(),
53 entry_count
: map
.iter_results(|results
| results
.count()),
54 local_def_id_keys
: None
,
56 map
.iter_results(|results
| {
57 for (key
, _
, _
) in results
{
58 key
.key_stats(&mut stats
)
64 pub fn print_stats(tcx
: TyCtxt
<'_
>) {
65 let queries
= query_stats(tcx
);
67 if cfg
!(debug_assertions
) {
68 let hits
: usize = queries
.iter().map(|s
| s
.cache_hits
).sum();
69 let results
: usize = queries
.iter().map(|s
| s
.entry_count
).sum();
70 eprintln
!("\nQuery cache hit rate: {}", hits
as f64 / (hits
+ results
) as f64);
73 let mut query_key_sizes
= queries
.clone();
74 query_key_sizes
.sort_by_key(|q
| q
.key_size
);
75 eprintln
!("\nLarge query keys:");
76 for q
in query_key_sizes
.iter().rev().filter(|q
| q
.key_size
> 8) {
77 eprintln
!(" {} - {} x {} - {}", q
.name
, q
.key_size
, q
.entry_count
, q
.key_type
);
80 let mut query_value_sizes
= queries
.clone();
81 query_value_sizes
.sort_by_key(|q
| q
.value_size
);
82 eprintln
!("\nLarge query values:");
83 for q
in query_value_sizes
.iter().rev().filter(|q
| q
.value_size
> 8) {
84 eprintln
!(" {} - {} x {} - {}", q
.name
, q
.value_size
, q
.entry_count
, q
.value_type
);
87 if cfg
!(debug_assertions
) {
88 let mut query_cache_hits
= queries
.clone();
89 query_cache_hits
.sort_by_key(|q
| q
.cache_hits
);
90 eprintln
!("\nQuery cache hits:");
91 for q
in query_cache_hits
.iter().rev() {
96 q
.cache_hits
as f64 / (q
.cache_hits
+ q
.entry_count
) as f64
101 let mut query_value_count
= queries
.clone();
102 query_value_count
.sort_by_key(|q
| q
.entry_count
);
103 eprintln
!("\nQuery value count:");
104 for q
in query_value_count
.iter().rev() {
105 eprintln
!(" {} - {}", q
.name
, q
.entry_count
);
108 let mut def_id_density
: Vec
<_
> =
109 queries
.iter().filter(|q
| q
.local_def_id_keys
.is_some()).collect();
110 def_id_density
.sort_by_key(|q
| q
.local_def_id_keys
.unwrap());
111 eprintln
!("\nLocal DefId density:");
112 let total
= tcx
.hir().definitions().def_index_count() as f64;
113 for q
in def_id_density
.iter().rev() {
114 let local
= q
.local_def_id_keys
.unwrap();
115 eprintln
!(" {} - {} = ({}%)", q
.name
, local
, (local
as f64 * 100.0) / total
);
119 macro_rules
! print_stats
{
121 $
($
(#[$attr:meta])* [$($modifiers:tt)*] fn $name:ident($K:ty) -> $V:ty,)*
123 fn query_stats(tcx
: TyCtxt
<'_
>) -> Vec
<QueryStats
> {
124 let mut queries
= Vec
::new();
127 queries
.push(stats
::<
128 query_storage
::$name
<'_
>,
131 &tcx
.query_caches
.$name
,
140 rustc_query_append
! { [print_stats!][<'tcx>] }