diff options
| author | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2025-06-24 15:39:42 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-06-24 15:39:42 +0200 |
| commit | e8dd3c356c037325bd85643f69367493a310d987 (patch) | |
| tree | be7833cbe3675fc34b9ed32748a5d9535cc0f857 | |
| parent | 0512c82cfa1ef2c6fa0ae7f7f3f057a64d1ae625 (diff) | |
| parent | b2a57e6b428689d8b6a9881f8ccdfd30d76767bc (diff) | |
| download | rust-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.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/rmeta/encoder.rs | 37 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/input_stats.rs | 61 | ||||
| -rw-r--r-- | tests/ui/stats/input-stats.stderr | 196 |
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 ================================================================ |
