Rollup merge of #133023 - samestep:hir-stats-total-count, r=nnethercote

Merge `-Zhir-stats` into `-Zinput-stats`

Currently `-Z hir-stats` prints the size and count of various kinds of nodes, and the total size of all the nodes it counted, but not the total count of nodes. So, before this PR:

```
$ git clone https://github.com/BurntSushi/ripgrep
$ cd ripgrep
$ cargo +nightly rustc -- -Z hir-stats
ast-stats-1 PRE EXPANSION AST STATS
ast-stats-1 Name                Accumulated Size         Count     Item Size
ast-stats-1 ----------------------------------------------------------------
ast-stats-1 ...
ast-stats-1 ----------------------------------------------------------------
ast-stats-1 Total                 93_576
ast-stats-1
ast-stats-2 POST EXPANSION AST STATS
ast-stats-2 Name                Accumulated Size         Count     Item Size
ast-stats-2 ----------------------------------------------------------------
ast-stats-2 ...
ast-stats-2 ----------------------------------------------------------------
ast-stats-2 Total              2_430_648
ast-stats-2
hir-stats HIR STATS
hir-stats Name                Accumulated Size         Count     Item Size
hir-stats ----------------------------------------------------------------
hir-stats ...
hir-stats ----------------------------------------------------------------
hir-stats Total              3_678_512
hir-stats
```

For consistency, this PR adds a total for the count as well:

```
$ cargo +stage1 rustc -- -Z hir-stats
ast-stats-1 PRE EXPANSION AST STATS
ast-stats-1 Name                Accumulated Size         Count     Item Size
ast-stats-1 ----------------------------------------------------------------
ast-stats-1 ...
ast-stats-1 ----------------------------------------------------------------
ast-stats-1 Total                 93_576                 1_877
ast-stats-1
ast-stats-2 POST EXPANSION AST STATS
ast-stats-2 Name                Accumulated Size         Count     Item Size
ast-stats-2 ----------------------------------------------------------------
ast-stats-2 ...
ast-stats-2 ----------------------------------------------------------------
ast-stats-2 Total              2_430_648                48_625
ast-stats-2
hir-stats HIR STATS
hir-stats Name                Accumulated Size         Count     Item Size
hir-stats ----------------------------------------------------------------
hir-stats ...
hir-stats ----------------------------------------------------------------
hir-stats Total              3_678_512                73_418
hir-stats
```

I wasn't sure if I was supposed to update `tests/ui/stats/hir-stats.stderr` to reflect this. I ran it locally, thinking it would fail, but it didn't:

```
$ ./x test tests/ui/stats
...

running 2 tests
i.

test result: ok. 1 passed; 0 failed; 1 ignored; 0 measured; 17949 filtered out
```

Also: is there a reason `-Z hir-stats` and `-Z input-stats` both exist? The former seems like it should completely supercede the latter. But strangely, the two give very different numbers for node counts:

```
$ cargo +nightly rustc -- -Z input-stats
...
Lines of code:             483
Pre-expansion node count:  2386
Post-expansion node count: 63844
```

That's a 30% difference in this case. Is it intentional that these numbers are so different? I see comments for both saying that they are merely approximations and should not be expected to be correct:

bd0826a452/compiler/rustc_ast_passes/src/node_count.rs (L1)

bd0826a452/compiler/rustc_passes/src/hir_stats.rs (L1-L3)
This commit is contained in:
Matthias Krüger 2024-11-19 09:19:20 +01:00 committed by GitHub
commit f25fee3349
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 24 additions and 165 deletions

View File

@ -18,7 +18,6 @@
pub mod ast_validation; pub mod ast_validation;
mod errors; mod errors;
pub mod feature_gate; pub mod feature_gate;
pub mod node_count;
pub mod show_span; pub mod show_span;
rustc_fluent_macro::fluent_messages! { "../messages.ftl" } rustc_fluent_macro::fluent_messages! { "../messages.ftl" }

View File

@ -1,129 +0,0 @@
// Simply gives a rough count of the number of nodes in an AST.
use rustc_ast::visit::*;
use rustc_ast::*;
use rustc_span::Span;
use rustc_span::symbol::Ident;
pub struct NodeCounter {
pub count: usize,
}
impl NodeCounter {
pub fn new() -> NodeCounter {
NodeCounter { count: 0 }
}
}
impl<'ast> Visitor<'ast> for NodeCounter {
fn visit_ident(&mut self, _ident: &Ident) {
self.count += 1;
}
fn visit_foreign_item(&mut self, i: &ForeignItem) {
self.count += 1;
walk_item(self, i)
}
fn visit_item(&mut self, i: &Item) {
self.count += 1;
walk_item(self, i)
}
fn visit_local(&mut self, l: &Local) {
self.count += 1;
walk_local(self, l)
}
fn visit_block(&mut self, b: &Block) {
self.count += 1;
walk_block(self, b)
}
fn visit_stmt(&mut self, s: &Stmt) {
self.count += 1;
walk_stmt(self, s)
}
fn visit_arm(&mut self, a: &Arm) {
self.count += 1;
walk_arm(self, a)
}
fn visit_pat(&mut self, p: &Pat) {
self.count += 1;
walk_pat(self, p)
}
fn visit_expr(&mut self, ex: &Expr) {
self.count += 1;
walk_expr(self, ex)
}
fn visit_ty(&mut self, t: &Ty) {
self.count += 1;
walk_ty(self, t)
}
fn visit_generic_param(&mut self, param: &GenericParam) {
self.count += 1;
walk_generic_param(self, param)
}
fn visit_generics(&mut self, g: &Generics) {
self.count += 1;
walk_generics(self, g)
}
fn visit_fn(&mut self, fk: visit::FnKind<'_>, _: Span, _: NodeId) {
self.count += 1;
walk_fn(self, fk)
}
fn visit_assoc_item(&mut self, ti: &AssocItem, ctxt: AssocCtxt) {
self.count += 1;
walk_assoc_item(self, ti, ctxt);
}
fn visit_trait_ref(&mut self, t: &TraitRef) {
self.count += 1;
walk_trait_ref(self, t)
}
fn visit_param_bound(&mut self, bounds: &GenericBound, _ctxt: BoundKind) {
self.count += 1;
walk_param_bound(self, bounds)
}
fn visit_poly_trait_ref(&mut self, t: &PolyTraitRef) {
self.count += 1;
walk_poly_trait_ref(self, t)
}
fn visit_variant_data(&mut self, s: &VariantData) {
self.count += 1;
walk_struct_def(self, s)
}
fn visit_field_def(&mut self, s: &FieldDef) {
self.count += 1;
walk_field_def(self, s)
}
fn visit_enum_def(&mut self, enum_definition: &EnumDef) {
self.count += 1;
walk_enum_def(self, enum_definition)
}
fn visit_variant(&mut self, v: &Variant) {
self.count += 1;
walk_variant(self, v)
}
fn visit_lifetime(&mut self, lifetime: &Lifetime, _: visit::LifetimeCtxt) {
self.count += 1;
walk_lifetime(self, lifetime)
}
fn visit_mac_call(&mut self, mac: &MacCall) {
self.count += 1;
walk_mac(self, mac)
}
fn visit_path(&mut self, path: &Path, _id: NodeId) {
self.count += 1;
walk_path(self, path)
}
fn visit_use_tree(&mut self, use_tree: &UseTree, id: NodeId, _nested: bool) {
self.count += 1;
walk_use_tree(self, use_tree, id)
}
fn visit_generic_args(&mut self, generic_args: &GenericArgs) {
self.count += 1;
walk_generic_args(self, generic_args)
}
fn visit_assoc_item_constraint(&mut self, constraint: &AssocItemConstraint) {
self.count += 1;
walk_assoc_item_constraint(self, constraint)
}
fn visit_attribute(&mut self, _attr: &Attribute) {
self.count += 1;
}
}

View File

@ -5,7 +5,7 @@ use std::path::{Path, PathBuf};
use std::sync::{Arc, LazyLock}; use std::sync::{Arc, LazyLock};
use std::{env, fs, iter}; use std::{env, fs, iter};
use rustc_ast::{self as ast, visit}; use rustc_ast as ast;
use rustc_codegen_ssa::traits::CodegenBackend; use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_data_structures::parallel; use rustc_data_structures::parallel;
use rustc_data_structures::steal::Steal; use rustc_data_structures::steal::Steal;
@ -24,7 +24,7 @@ use rustc_middle::util::Providers;
use rustc_parse::{ use rustc_parse::{
new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal, validate_attr, new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal, validate_attr,
}; };
use rustc_passes::{abi_test, hir_stats, layout_test}; use rustc_passes::{abi_test, input_stats, layout_test};
use rustc_resolve::Resolver; use rustc_resolve::Resolver;
use rustc_session::code_stats::VTableSizeInfo; use rustc_session::code_stats::VTableSizeInfo;
use rustc_session::config::{CrateType, Input, OutFileName, OutputFilenames, OutputType}; use rustc_session::config::{CrateType, Input, OutFileName, OutputFilenames, OutputType};
@ -54,28 +54,17 @@ pub(crate) fn parse<'a>(sess: &'a Session) -> Result<ast::Crate> {
}) })
.map_err(|parse_error| parse_error.emit())?; .map_err(|parse_error| parse_error.emit())?;
if sess.opts.unstable_opts.input_stats {
eprintln!("Lines of code: {}", sess.source_map().count_lines());
eprintln!("Pre-expansion node count: {}", count_nodes(&krate));
}
if let Some(ref s) = sess.opts.unstable_opts.show_span { if let Some(ref s) = sess.opts.unstable_opts.show_span {
rustc_ast_passes::show_span::run(sess.dcx(), s, &krate); rustc_ast_passes::show_span::run(sess.dcx(), s, &krate);
} }
if sess.opts.unstable_opts.hir_stats { if sess.opts.unstable_opts.input_stats {
hir_stats::print_ast_stats(&krate, "PRE EXPANSION AST STATS", "ast-stats-1"); input_stats::print_ast_stats(&krate, "PRE EXPANSION AST STATS", "ast-stats-1");
} }
Ok(krate) Ok(krate)
} }
fn count_nodes(krate: &ast::Crate) -> usize {
let mut counter = rustc_ast_passes::node_count::NodeCounter::new();
visit::walk_crate(&mut counter, krate);
counter.count
}
fn pre_expansion_lint<'a>( fn pre_expansion_lint<'a>(
sess: &Session, sess: &Session,
features: &Features, features: &Features,
@ -290,11 +279,7 @@ fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) {
let mut lint_buffer = resolver.lint_buffer.steal(); let mut lint_buffer = resolver.lint_buffer.steal();
if sess.opts.unstable_opts.input_stats { if sess.opts.unstable_opts.input_stats {
eprintln!("Post-expansion node count: {}", count_nodes(krate)); input_stats::print_ast_stats(krate, "POST EXPANSION AST STATS", "ast-stats-2");
}
if sess.opts.unstable_opts.hir_stats {
hir_stats::print_ast_stats(krate, "POST EXPANSION AST STATS", "ast-stats-2");
} }
// Needs to go *after* expansion to be able to check the results of macro expansion. // Needs to go *after* expansion to be able to check the results of macro expansion.
@ -820,8 +805,8 @@ pub(crate) fn create_global_ctxt<'tcx>(
/// Runs all analyses that we guarantee to run, even if errors were reported in earlier analyses. /// Runs all analyses that we guarantee to run, even if errors were reported in earlier analyses.
/// This function never fails. /// This function never fails.
fn run_required_analyses(tcx: TyCtxt<'_>) { fn run_required_analyses(tcx: TyCtxt<'_>) {
if tcx.sess.opts.unstable_opts.hir_stats { if tcx.sess.opts.unstable_opts.input_stats {
rustc_passes::hir_stats::print_hir_stats(tcx); rustc_passes::input_stats::print_hir_stats(tcx);
} }
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
rustc_passes::hir_id_validator::check_crate(tcx); rustc_passes::hir_id_validator::check_crate(tcx);

View File

@ -698,7 +698,6 @@ fn test_unstable_options_tracking_hash() {
untracked!(dylib_lto, true); untracked!(dylib_lto, true);
untracked!(emit_stack_sizes, true); untracked!(emit_stack_sizes, true);
untracked!(future_incompat_test, true); untracked!(future_incompat_test, true);
untracked!(hir_stats, true);
untracked!(identify_regions, true); untracked!(identify_regions, true);
untracked!(incremental_info, true); untracked!(incremental_info, true);
untracked!(incremental_verify_ich, true); untracked!(incremental_verify_ich, true);

View File

@ -126,6 +126,7 @@ impl<'k> StatCollector<'k> {
}); });
let total_size = nodes.iter().map(|(_, node)| node.stats.count * node.stats.size).sum(); let total_size = nodes.iter().map(|(_, node)| node.stats.count * node.stats.size).sum();
let total_count = nodes.iter().map(|(_, node)| node.stats.count).sum();
eprintln!("{prefix} {title}"); eprintln!("{prefix} {title}");
eprintln!( eprintln!(
@ -167,7 +168,13 @@ impl<'k> StatCollector<'k> {
} }
} }
eprintln!("{prefix} ----------------------------------------------------------------"); eprintln!("{prefix} ----------------------------------------------------------------");
eprintln!("{} {:<18}{:>10}", prefix, "Total", to_readable_str(total_size)); eprintln!(
"{} {:<18}{:>10} {:>14}",
prefix,
"Total",
to_readable_str(total_size),
to_readable_str(total_count),
);
eprintln!("{prefix}"); eprintln!("{prefix}");
} }
} }

View File

@ -27,7 +27,7 @@ pub mod entry;
mod errors; mod errors;
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
pub mod hir_id_validator; pub mod hir_id_validator;
pub mod hir_stats; pub mod input_stats;
mod lang_items; mod lang_items;
pub mod layout_test; pub mod layout_test;
mod lib_features; mod lib_features;

View File

@ -1805,8 +1805,6 @@ options! {
environment variable `RUSTC_GRAPHVIZ_FONT` (default: `Courier, monospace`)"), environment variable `RUSTC_GRAPHVIZ_FONT` (default: `Courier, monospace`)"),
has_thread_local: Option<bool> = (None, parse_opt_bool, [TRACKED], has_thread_local: Option<bool> = (None, parse_opt_bool, [TRACKED],
"explicitly enable the `cfg(target_thread_local)` directive"), "explicitly enable the `cfg(target_thread_local)` directive"),
hir_stats: bool = (false, parse_bool, [UNTRACKED],
"print some statistics about AST and HIR (default: no)"),
human_readable_cgu_names: bool = (false, parse_bool, [TRACKED], human_readable_cgu_names: bool = (false, parse_bool, [TRACKED],
"generate human-readable, predictable names for codegen units (default: no)"), "generate human-readable, predictable names for codegen units (default: no)"),
identify_regions: bool = (false, parse_bool, [UNTRACKED], identify_regions: bool = (false, parse_bool, [UNTRACKED],
@ -1838,7 +1836,7 @@ options! {
inline_mir_threshold: Option<usize> = (None, parse_opt_number, [TRACKED], inline_mir_threshold: Option<usize> = (None, parse_opt_number, [TRACKED],
"a default MIR inlining threshold (default: 50)"), "a default MIR inlining threshold (default: 50)"),
input_stats: bool = (false, parse_bool, [UNTRACKED], input_stats: bool = (false, parse_bool, [UNTRACKED],
"gather statistics about the input (default: no)"), "print some statistics about AST and HIR (default: no)"),
instrument_mcount: bool = (false, parse_bool, [TRACKED], instrument_mcount: bool = (false, parse_bool, [TRACKED],
"insert function instrument code for mcount-based tracing (default: no)"), "insert function instrument code for mcount-based tracing (default: no)"),
instrument_xray: Option<InstrumentXRay> = (None, parse_instrument_xray, [TRACKED], instrument_xray: Option<InstrumentXRay> = (None, parse_instrument_xray, [TRACKED],

View File

@ -1,6 +1,6 @@
//@ check-pass //@ check-pass
//@ compile-flags: -Zhir-stats //@ compile-flags: -Zinput-stats
//@ only-x86_64 //@ only-64bit
// layout randomization affects the hir stat output // layout randomization affects the hir stat output
//@ needs-deterministic-layouts //@ needs-deterministic-layouts
@ -11,7 +11,7 @@
// The aim here is to include at least one of every different type of top-level // The aim here is to include at least one of every different type of top-level
// AST/HIR node reported by `-Zhir-stats`. // AST/HIR node reported by `-Zinput-stats`.
#![allow(dead_code)] #![allow(dead_code)]

View File

@ -53,7 +53,7 @@ ast-stats-1 - Enum 136 ( 2.0%) 1
ast-stats-1 - Fn 272 ( 4.1%) 2 ast-stats-1 - Fn 272 ( 4.1%) 2
ast-stats-1 - Use 408 ( 6.1%) 3 ast-stats-1 - Use 408 ( 6.1%) 3
ast-stats-1 ---------------------------------------------------------------- ast-stats-1 ----------------------------------------------------------------
ast-stats-1 Total 6_640 ast-stats-1 Total 6_640 116
ast-stats-1 ast-stats-1
ast-stats-2 POST EXPANSION AST STATS ast-stats-2 POST EXPANSION AST STATS
ast-stats-2 Name Accumulated Size Count Item Size ast-stats-2 Name Accumulated Size Count Item Size
@ -113,7 +113,7 @@ ast-stats-2 - ForeignMod 136 ( 1.9%) 1
ast-stats-2 - Fn 272 ( 3.7%) 2 ast-stats-2 - Fn 272 ( 3.7%) 2
ast-stats-2 - Use 544 ( 7.5%) 4 ast-stats-2 - Use 544 ( 7.5%) 4
ast-stats-2 ---------------------------------------------------------------- ast-stats-2 ----------------------------------------------------------------
ast-stats-2 Total 7_288 ast-stats-2 Total 7_288 127
ast-stats-2 ast-stats-2
hir-stats HIR STATS hir-stats HIR STATS
hir-stats Name Accumulated Size Count Item Size hir-stats Name Accumulated Size Count Item Size
@ -174,5 +174,5 @@ hir-stats - Use 352 ( 3.9%) 4
hir-stats Path 1_240 (13.7%) 31 40 hir-stats Path 1_240 (13.7%) 31 40
hir-stats PathSegment 1_920 (21.3%) 40 48 hir-stats PathSegment 1_920 (21.3%) 40 48
hir-stats ---------------------------------------------------------------- hir-stats ----------------------------------------------------------------
hir-stats Total 9_024 hir-stats Total 9_024 180
hir-stats hir-stats

View File

@ -901,7 +901,7 @@ message = "This PR changes a file inside `tests/crashes`. If a crash was fixed,
message = "Changes to the code generated for builtin derived traits." message = "Changes to the code generated for builtin derived traits."
cc = ["@nnethercote"] cc = ["@nnethercote"]
[mentions."tests/ui/stats/hir-stats.stderr"] [mentions."tests/ui/stats/input-stats.stderr"]
message = "Changes to the size of AST and/or HIR nodes." message = "Changes to the size of AST and/or HIR nodes."
cc = ["@nnethercote"] cc = ["@nnethercote"]