1 use crate::ty
::query
::config
::QueryAccessors
;
2 use crate::ty
::query
::plumbing
::QueryState
;
3 use crate::ty
::query
::queries
;
5 use rustc_hir
::def_id
::{DefId, LOCAL_CRATE}
;
7 use std
::any
::type_name
;
9 #[cfg(debug_assertions)]
10 use std
::sync
::atomic
::Ordering
;
13 fn key_stats(&self, stats
: &mut QueryStats
);
16 impl<T
> KeyStats
for T
{
17 default fn key_stats(&self, _
: &mut QueryStats
) {}
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);
33 key_type
: &'
static str,
35 value_type
: &'
static str,
37 local_def_id_keys
: Option
<usize>,
40 fn stats
<'tcx
, Q
: QueryAccessors
<'tcx
>>(
42 map
: &QueryState
<'tcx
, Q
>,
44 let mut stats
= QueryStats
{
46 #[cfg(debug_assertions)]
47 cache_hits
: map
.cache_hits
.load(Ordering
::Relaxed
),
48 #[cfg(not(debug_assertions))]
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
,
57 map
.iter_results(|results
| {
58 for (key
, _
, _
) in results
{
59 key
.key_stats(&mut stats
)
65 pub fn print_stats(tcx
: TyCtxt
<'_
>) {
66 let queries
= query_stats(tcx
);
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);
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
);
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
);
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() {
97 q
.cache_hits
as f64 / (q
.cache_hits
+ q
.entry_count
) as f64
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
);
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
);
120 macro_rules
! print_stats
{
121 (<$tcx
:tt
> $
($category
:tt
{
122 $
($
(#[$attr:meta])* [$($modifiers:tt)*] fn $name:ident: $node:ident($K:ty) -> $V:ty,)*
124 fn query_stats(tcx
: TyCtxt
<'_
>) -> Vec
<QueryStats
> {
125 let mut queries
= Vec
::new();
128 queries
.push(stats
::<queries
::$name
<'_
>>(
139 rustc_query_append
! { [print_stats!][<'tcx>] }