about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2025-06-24 15:39:42 +0200
committerGitHub <noreply@github.com>2025-06-24 15:39:42 +0200
commite8dd3c356c037325bd85643f69367493a310d987 (patch)
treebe7833cbe3675fc34b9ed32748a5d9535cc0f857
parent0512c82cfa1ef2c6fa0ae7f7f3f057a64d1ae625 (diff)
parentb2a57e6b428689d8b6a9881f8ccdfd30d76767bc (diff)
downloadrust-e8dd3c356c037325bd85643f69367493a310d987.tar.gz
rust-e8dd3c356c037325bd85643f69367493a310d987.zip
Rollup merge of #142944 - nnethercote:stats-tweaks, r=lqd
Stats output tweaks

Some improvements to `-Zinput-stats` and `-Zmeta-stat` inspired by the new `-Zmacro-stats`.

r? `@lqd`
-rw-r--r--compiler/rustc_interface/src/passes.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs37
-rw-r--r--compiler/rustc_passes/src/input_stats.rs61
-rw-r--r--tests/ui/stats/input-stats.stderr196
4 files changed, 167 insertions, 129 deletions
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 0b9facfc7af..e8c23ef997c 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -371,7 +371,7 @@ fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) {
     let mut lint_buffer = resolver.lint_buffer.steal();
 
     if sess.opts.unstable_opts.input_stats {
-        input_stats::print_ast_stats(krate, "POST EXPANSION AST STATS", "ast-stats");
+        input_stats::print_ast_stats(tcx, krate);
     }
 
     // Needs to go *after* expansion to be able to check the results of macro expansion.
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 00bd32eb0eb..ed3c18a02a6 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -762,6 +762,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         assert_eq!(total_bytes, computed_total_bytes);
 
         if tcx.sess.opts.unstable_opts.meta_stats {
+            use std::fmt::Write;
+
             self.opaque.flush();
 
             // Rewind and re-read all the metadata to count the zero bytes we wrote.
@@ -777,31 +779,44 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             assert_eq!(self.opaque.file().stream_position().unwrap(), pos_before_rewind);
 
             stats.sort_by_key(|&(_, usize)| usize);
+            stats.reverse(); // bigger items first
 
             let prefix = "meta-stats";
             let perc = |bytes| (bytes * 100) as f64 / total_bytes as f64;
 
-            eprintln!("{prefix} METADATA STATS");
-            eprintln!("{} {:<23}{:>10}", prefix, "Section", "Size");
-            eprintln!("{prefix} ----------------------------------------------------------------");
+            let section_w = 23;
+            let size_w = 10;
+            let banner_w = 64;
+
+            // We write all the text into a string and print it with a single
+            // `eprint!`. This is an attempt to minimize interleaved text if multiple
+            // rustc processes are printing macro-stats at the same time (e.g. with
+            // `RUSTFLAGS='-Zmeta-stats' cargo build`). It still doesn't guarantee
+            // non-interleaving, though.
+            let mut s = String::new();
+            _ = writeln!(s, "{prefix} {}", "=".repeat(banner_w));
+            _ = writeln!(s, "{prefix} METADATA STATS: {}", tcx.crate_name(LOCAL_CRATE));
+            _ = writeln!(s, "{prefix} {:<section_w$}{:>size_w$}", "Section", "Size");
+            _ = writeln!(s, "{prefix} {}", "-".repeat(banner_w));
             for (label, size) in stats {
-                eprintln!(
-                    "{} {:<23}{:>10} ({:4.1}%)",
-                    prefix,
+                _ = writeln!(
+                    s,
+                    "{prefix} {:<section_w$}{:>size_w$} ({:4.1}%)",
                     label,
                     usize_with_underscores(size),
                     perc(size)
                 );
             }
-            eprintln!("{prefix} ----------------------------------------------------------------");
-            eprintln!(
-                "{} {:<23}{:>10} (of which {:.1}% are zero bytes)",
-                prefix,
+            _ = writeln!(s, "{prefix} {}", "-".repeat(banner_w));
+            _ = writeln!(
+                s,
+                "{prefix} {:<section_w$}{:>size_w$} (of which {:.1}% are zero bytes)",
                 "Total",
                 usize_with_underscores(total_bytes),
                 perc(zero_bytes)
             );
-            eprintln!("{prefix}");
+            _ = writeln!(s, "{prefix} {}", "=".repeat(banner_w));
+            eprint!("{s}");
         }
 
         root
diff --git a/compiler/rustc_passes/src/input_stats.rs b/compiler/rustc_passes/src/input_stats.rs
index 46e6c0bf7da..40bc18939d6 100644
--- a/compiler/rustc_passes/src/input_stats.rs
+++ b/compiler/rustc_passes/src/input_stats.rs
@@ -65,16 +65,16 @@ pub fn print_hir_stats(tcx: TyCtxt<'_>) {
         StatCollector { tcx: Some(tcx), nodes: FxHashMap::default(), seen: FxHashSet::default() };
     tcx.hir_walk_toplevel_module(&mut collector);
     tcx.hir_walk_attributes(&mut collector);
-    collector.print("HIR STATS", "hir-stats");
+    collector.print(tcx, "HIR STATS", "hir-stats");
 }
 
-pub fn print_ast_stats(krate: &ast::Crate, title: &str, prefix: &str) {
+pub fn print_ast_stats(tcx: TyCtxt<'_>, krate: &ast::Crate) {
     use rustc_ast::visit::Visitor;
 
     let mut collector =
         StatCollector { tcx: None, nodes: FxHashMap::default(), seen: FxHashSet::default() };
     collector.visit_crate(krate);
-    collector.print(title, prefix);
+    collector.print(tcx, "POST EXPANSION AST STATS", "ast-stats");
 }
 
 impl<'k> StatCollector<'k> {
@@ -116,29 +116,48 @@ impl<'k> StatCollector<'k> {
         }
     }
 
-    fn print(&self, title: &str, prefix: &str) {
+    fn print(&self, tcx: TyCtxt<'_>, title: &str, prefix: &str) {
+        use std::fmt::Write;
+
         // We will soon sort, so the initial order does not matter.
         #[allow(rustc::potential_query_instability)]
         let mut nodes: Vec<_> = self.nodes.iter().collect();
         nodes.sort_by_cached_key(|(label, node)| (node.stats.accum_size(), label.to_owned()));
+        nodes.reverse(); // bigger items first
+
+        let name_w = 18;
+        let acc_size1_w = 10;
+        let acc_size2_w = 8; // " (NN.N%)"
+        let acc_size_w = acc_size1_w + acc_size2_w;
+        let count_w = 14;
+        let item_size_w = 14;
+        let banner_w = name_w + acc_size_w + count_w + item_size_w;
 
         let total_size = nodes.iter().map(|(_, node)| node.stats.accum_size()).sum();
         let total_count = nodes.iter().map(|(_, node)| node.stats.count).sum();
 
-        eprintln!("{prefix} {title}");
-        eprintln!(
-            "{} {:<18}{:>18}{:>14}{:>14}",
-            prefix, "Name", "Accumulated Size", "Count", "Item Size"
+        // We write all the text into a string and print it with a single
+        // `eprint!`. This is an attempt to minimize interleaved text if multiple
+        // rustc processes are printing macro-stats at the same time (e.g. with
+        // `RUSTFLAGS='-Zinput-stats' cargo build`). It still doesn't guarantee
+        // non-interleaving, though.
+        let mut s = String::new();
+        _ = writeln!(s, "{prefix} {}", "=".repeat(banner_w));
+        _ = writeln!(s, "{prefix} {title}: {}", tcx.crate_name(hir::def_id::LOCAL_CRATE));
+        _ = writeln!(
+            s,
+            "{prefix} {:<name_w$}{:>acc_size_w$}{:>count_w$}{:>item_size_w$}",
+            "Name", "Accumulated Size", "Count", "Item Size"
         );
-        eprintln!("{prefix} ----------------------------------------------------------------");
+        _ = writeln!(s, "{prefix} {}", "-".repeat(banner_w));
 
         let percent = |m, n| (m * 100) as f64 / n as f64;
 
         for (label, node) in nodes {
             let size = node.stats.accum_size();
-            eprintln!(
-                "{} {:<18}{:>10} ({:4.1}%){:>14}{:>14}",
-                prefix,
+            _ = writeln!(
+                s,
+                "{prefix} {:<name_w$}{:>acc_size1_w$} ({:4.1}%){:>count_w$}{:>item_size_w$}",
                 label,
                 usize_with_underscores(size),
                 percent(size, total_size),
@@ -155,9 +174,9 @@ impl<'k> StatCollector<'k> {
 
                 for (label, subnode) in subnodes {
                     let size = subnode.accum_size();
-                    eprintln!(
-                        "{} - {:<18}{:>10} ({:4.1}%){:>14}",
-                        prefix,
+                    _ = writeln!(
+                        s,
+                        "{prefix} - {:<name_w$}{:>acc_size1_w$} ({:4.1}%){:>count_w$}",
                         label,
                         usize_with_underscores(size),
                         percent(size, total_size),
@@ -166,15 +185,17 @@ impl<'k> StatCollector<'k> {
                 }
             }
         }
-        eprintln!("{prefix} ----------------------------------------------------------------");
-        eprintln!(
-            "{} {:<18}{:>10}        {:>14}",
-            prefix,
+        _ = writeln!(s, "{prefix} {}", "-".repeat(banner_w));
+        _ = writeln!(
+            s,
+            "{prefix} {:<name_w$}{:>acc_size1_w$}{:>acc_size2_w$}{:>count_w$}",
             "Total",
             usize_with_underscores(total_size),
+            "",
             usize_with_underscores(total_count),
         );
-        eprintln!("{prefix}");
+        _ = writeln!(s, "{prefix} {}", "=".repeat(banner_w));
+        eprint!("{s}");
     }
 }
 
diff --git a/tests/ui/stats/input-stats.stderr b/tests/ui/stats/input-stats.stderr
index 88f91bef30b..b3b8784fa27 100644
--- a/tests/ui/stats/input-stats.stderr
+++ b/tests/ui/stats/input-stats.stderr
@@ -1,52 +1,7 @@
-ast-stats POST EXPANSION AST STATS
+ast-stats ================================================================
+ast-stats POST EXPANSION AST STATS: input_stats
 ast-stats Name                Accumulated Size         Count     Item Size
 ast-stats ----------------------------------------------------------------
-ast-stats Crate                     40 (NN.N%)             1            40
-ast-stats GenericArgs               40 (NN.N%)             1            40
-ast-stats - AngleBracketed            40 (NN.N%)             1
-ast-stats ExprField                 48 (NN.N%)             1            48
-ast-stats WherePredicate            72 (NN.N%)             1            72
-ast-stats - BoundPredicate            72 (NN.N%)             1
-ast-stats ForeignItem               80 (NN.N%)             1            80
-ast-stats - Fn                        80 (NN.N%)             1
-ast-stats Arm                       96 (NN.N%)             2            48
-ast-stats Local                     96 (NN.N%)             1            96
-ast-stats FnDecl                   120 (NN.N%)             5            24
-ast-stats InlineAsm                120 (NN.N%)             1           120
-ast-stats Attribute                128 (NN.N%)             4            32
-ast-stats - DocComment                32 (NN.N%)             1
-ast-stats - Normal                    96 (NN.N%)             3
-ast-stats Param                    160 (NN.N%)             4            40
-ast-stats Stmt                     160 (NN.N%)             5            32
-ast-stats - Let                       32 (NN.N%)             1
-ast-stats - Semi                      32 (NN.N%)             1
-ast-stats - Expr                      96 (NN.N%)             3
-ast-stats Block                    192 (NN.N%)             6            32
-ast-stats FieldDef                 208 (NN.N%)             2           104
-ast-stats Variant                  208 (NN.N%)             2           104
-ast-stats AssocItem                320 (NN.N%)             4            80
-ast-stats - Fn                       160 (NN.N%)             2
-ast-stats - Type                     160 (NN.N%)             2
-ast-stats GenericBound             352 (NN.N%)             4            88
-ast-stats - Trait                    352 (NN.N%)             4
-ast-stats GenericParam             480 (NN.N%)             5            96
-ast-stats Pat                      504 (NN.N%)             7            72
-ast-stats - Struct                    72 (NN.N%)             1
-ast-stats - Wild                      72 (NN.N%)             1
-ast-stats - Ident                    360 (NN.N%)             5
-ast-stats Expr                     648 (NN.N%)             9            72
-ast-stats - InlineAsm                 72 (NN.N%)             1
-ast-stats - Match                     72 (NN.N%)             1
-ast-stats - Path                      72 (NN.N%)             1
-ast-stats - Struct                    72 (NN.N%)             1
-ast-stats - Lit                      144 (NN.N%)             2
-ast-stats - Block                    216 (NN.N%)             3
-ast-stats PathSegment              864 (NN.N%)            36            24
-ast-stats Ty                       896 (NN.N%)            14            64
-ast-stats - Ptr                       64 (NN.N%)             1
-ast-stats - Ref                       64 (NN.N%)             1
-ast-stats - ImplicitSelf             128 (NN.N%)             2
-ast-stats - Path                     640 (NN.N%)            10
 ast-stats Item                   1_584 (NN.N%)            11           144
 ast-stats - Enum                     144 (NN.N%)             1
 ast-stats - ExternCrate              144 (NN.N%)             1
@@ -55,57 +10,61 @@ ast-stats - Impl                     144 (NN.N%)             1
 ast-stats - Trait                    144 (NN.N%)             1
 ast-stats - Fn                       288 (NN.N%)             2
 ast-stats - Use                      576 (NN.N%)             4
+ast-stats Ty                       896 (NN.N%)            14            64
+ast-stats - Ptr                       64 (NN.N%)             1
+ast-stats - Ref                       64 (NN.N%)             1
+ast-stats - ImplicitSelf             128 (NN.N%)             2
+ast-stats - Path                     640 (NN.N%)            10
+ast-stats PathSegment              864 (NN.N%)            36            24
+ast-stats Expr                     648 (NN.N%)             9            72
+ast-stats - InlineAsm                 72 (NN.N%)             1
+ast-stats - Match                     72 (NN.N%)             1
+ast-stats - Path                      72 (NN.N%)             1
+ast-stats - Struct                    72 (NN.N%)             1
+ast-stats - Lit                      144 (NN.N%)             2
+ast-stats - Block                    216 (NN.N%)             3
+ast-stats Pat                      504 (NN.N%)             7            72
+ast-stats - Struct                    72 (NN.N%)             1
+ast-stats - Wild                      72 (NN.N%)             1
+ast-stats - Ident                    360 (NN.N%)             5
+ast-stats GenericParam             480 (NN.N%)             5            96
+ast-stats GenericBound             352 (NN.N%)             4            88
+ast-stats - Trait                    352 (NN.N%)             4
+ast-stats AssocItem                320 (NN.N%)             4            80
+ast-stats - Fn                       160 (NN.N%)             2
+ast-stats - Type                     160 (NN.N%)             2
+ast-stats Variant                  208 (NN.N%)             2           104
+ast-stats FieldDef                 208 (NN.N%)             2           104
+ast-stats Block                    192 (NN.N%)             6            32
+ast-stats Stmt                     160 (NN.N%)             5            32
+ast-stats - Let                       32 (NN.N%)             1
+ast-stats - Semi                      32 (NN.N%)             1
+ast-stats - Expr                      96 (NN.N%)             3
+ast-stats Param                    160 (NN.N%)             4            40
+ast-stats Attribute                128 (NN.N%)             4            32
+ast-stats - DocComment                32 (NN.N%)             1
+ast-stats - Normal                    96 (NN.N%)             3
+ast-stats InlineAsm                120 (NN.N%)             1           120
+ast-stats FnDecl                   120 (NN.N%)             5            24
+ast-stats Local                     96 (NN.N%)             1            96
+ast-stats Arm                       96 (NN.N%)             2            48
+ast-stats ForeignItem               80 (NN.N%)             1            80
+ast-stats - Fn                        80 (NN.N%)             1
+ast-stats WherePredicate            72 (NN.N%)             1            72
+ast-stats - BoundPredicate            72 (NN.N%)             1
+ast-stats ExprField                 48 (NN.N%)             1            48
+ast-stats GenericArgs               40 (NN.N%)             1            40
+ast-stats - AngleBracketed            40 (NN.N%)             1
+ast-stats Crate                     40 (NN.N%)             1            40
 ast-stats ----------------------------------------------------------------
 ast-stats Total                  7_416                   127
-ast-stats
-hir-stats HIR STATS
+ast-stats ================================================================
+hir-stats ================================================================
+hir-stats HIR STATS: input_stats
 hir-stats Name                Accumulated Size         Count     Item Size
 hir-stats ----------------------------------------------------------------
-hir-stats ForeignItemRef            24 (NN.N%)             1            24
-hir-stats Lifetime                  28 (NN.N%)             1            28
-hir-stats Mod                       32 (NN.N%)             1            32
-hir-stats ExprField                 40 (NN.N%)             1            40
-hir-stats TraitItemRef              56 (NN.N%)             2            28
-hir-stats GenericArg                64 (NN.N%)             4            16
-hir-stats - Type                      16 (NN.N%)             1
-hir-stats - Lifetime                  48 (NN.N%)             3
-hir-stats Param                     64 (NN.N%)             2            32
-hir-stats Body                      72 (NN.N%)             3            24
-hir-stats ImplItemRef               72 (NN.N%)             2            36
-hir-stats InlineAsm                 72 (NN.N%)             1            72
-hir-stats Local                     72 (NN.N%)             1            72
-hir-stats WherePredicate            72 (NN.N%)             3            24
-hir-stats - BoundPredicate            72 (NN.N%)             3
-hir-stats Arm                       80 (NN.N%)             2            40
-hir-stats Stmt                      96 (NN.N%)             3            32
-hir-stats - Expr                      32 (NN.N%)             1
-hir-stats - Let                       32 (NN.N%)             1
-hir-stats - Semi                      32 (NN.N%)             1
-hir-stats FnDecl                   120 (NN.N%)             3            40
-hir-stats FieldDef                 128 (NN.N%)             2            64
-hir-stats GenericArgs              144 (NN.N%)             3            48
-hir-stats Variant                  144 (NN.N%)             2            72
-hir-stats Attribute                160 (NN.N%)             4            40
-hir-stats GenericBound             256 (NN.N%)             4            64
-hir-stats - Trait                    256 (NN.N%)             4
-hir-stats Block                    288 (NN.N%)             6            48
-hir-stats Pat                      360 (NN.N%)             5            72
-hir-stats - Struct                    72 (NN.N%)             1
-hir-stats - Wild                      72 (NN.N%)             1
-hir-stats - Binding                  216 (NN.N%)             3
-hir-stats GenericParam             400 (NN.N%)             5            80
-hir-stats Generics                 560 (NN.N%)            10            56
-hir-stats Ty                       720 (NN.N%)            15            48
-hir-stats - Ptr                       48 (NN.N%)             1
-hir-stats - Ref                       48 (NN.N%)             1
-hir-stats - Path                     624 (NN.N%)            13
-hir-stats Expr                     768 (NN.N%)            12            64
-hir-stats - InlineAsm                 64 (NN.N%)             1
-hir-stats - Match                     64 (NN.N%)             1
-hir-stats - Path                      64 (NN.N%)             1
-hir-stats - Struct                    64 (NN.N%)             1
-hir-stats - Lit                      128 (NN.N%)             2
-hir-stats - Block                    384 (NN.N%)             6
+hir-stats PathSegment            1_776 (NN.N%)            37            48
+hir-stats Path                   1_040 (NN.N%)            26            40
 hir-stats Item                     968 (NN.N%)            11            88
 hir-stats - Enum                      88 (NN.N%)             1
 hir-stats - ExternCrate               88 (NN.N%)             1
@@ -114,8 +73,51 @@ hir-stats - Impl                      88 (NN.N%)             1
 hir-stats - Trait                     88 (NN.N%)             1
 hir-stats - Fn                       176 (NN.N%)             2
 hir-stats - Use                      352 (NN.N%)             4
-hir-stats Path                   1_040 (NN.N%)            26            40
-hir-stats PathSegment            1_776 (NN.N%)            37            48
+hir-stats Expr                     768 (NN.N%)            12            64
+hir-stats - InlineAsm                 64 (NN.N%)             1
+hir-stats - Match                     64 (NN.N%)             1
+hir-stats - Path                      64 (NN.N%)             1
+hir-stats - Struct                    64 (NN.N%)             1
+hir-stats - Lit                      128 (NN.N%)             2
+hir-stats - Block                    384 (NN.N%)             6
+hir-stats Ty                       720 (NN.N%)            15            48
+hir-stats - Ptr                       48 (NN.N%)             1
+hir-stats - Ref                       48 (NN.N%)             1
+hir-stats - Path                     624 (NN.N%)            13
+hir-stats Generics                 560 (NN.N%)            10            56
+hir-stats GenericParam             400 (NN.N%)             5            80
+hir-stats Pat                      360 (NN.N%)             5            72
+hir-stats - Struct                    72 (NN.N%)             1
+hir-stats - Wild                      72 (NN.N%)             1
+hir-stats - Binding                  216 (NN.N%)             3
+hir-stats Block                    288 (NN.N%)             6            48
+hir-stats GenericBound             256 (NN.N%)             4            64
+hir-stats - Trait                    256 (NN.N%)             4
+hir-stats Attribute                160 (NN.N%)             4            40
+hir-stats Variant                  144 (NN.N%)             2            72
+hir-stats GenericArgs              144 (NN.N%)             3            48
+hir-stats FieldDef                 128 (NN.N%)             2            64
+hir-stats FnDecl                   120 (NN.N%)             3            40
+hir-stats Stmt                      96 (NN.N%)             3            32
+hir-stats - Expr                      32 (NN.N%)             1
+hir-stats - Let                       32 (NN.N%)             1
+hir-stats - Semi                      32 (NN.N%)             1
+hir-stats Arm                       80 (NN.N%)             2            40
+hir-stats WherePredicate            72 (NN.N%)             3            24
+hir-stats - BoundPredicate            72 (NN.N%)             3
+hir-stats Local                     72 (NN.N%)             1            72
+hir-stats InlineAsm                 72 (NN.N%)             1            72
+hir-stats ImplItemRef               72 (NN.N%)             2            36
+hir-stats Body                      72 (NN.N%)             3            24
+hir-stats Param                     64 (NN.N%)             2            32
+hir-stats GenericArg                64 (NN.N%)             4            16
+hir-stats - Type                      16 (NN.N%)             1
+hir-stats - Lifetime                  48 (NN.N%)             3
+hir-stats TraitItemRef              56 (NN.N%)             2            28
+hir-stats ExprField                 40 (NN.N%)             1            40
+hir-stats Mod                       32 (NN.N%)             1            32
+hir-stats Lifetime                  28 (NN.N%)             1            28
+hir-stats ForeignItemRef            24 (NN.N%)             1            24
 hir-stats ----------------------------------------------------------------
 hir-stats Total                  8_676                   172
-hir-stats
+hir-stats ================================================================