Skip to content

Commit 288b667

Browse files
committed
Improve AST stat collector.
This commit: - Adds a comment explaining which `visit_*` methods should be implemented. - Adds and removes some `visit_*` methods accordingly, improving coverage, and avoiding some double counting.
1 parent bf20777 commit 288b667

File tree

2 files changed

+81
-18
lines changed

2 files changed

+81
-18
lines changed

compiler/rustc_passes/src/hir_stats.rs

Lines changed: 66 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,23 @@ struct NodeData {
2626
size: usize,
2727
}
2828

29+
/// This type measures the size of AST and HIR nodes, by implementing the AST
30+
/// and HIR `Visitor` traits. But we don't measure every visited type because
31+
/// that could cause double counting.
32+
///
33+
/// For example, `ast::Visitor` has `visit_ident`, but `Ident`s are always
34+
/// stored inline within other AST nodes, so we don't implement `visit_ident`
35+
/// here. In constrast, we do implement `visit_expr` because `ast::Expr` is
36+
/// always stored as `P<ast::Expr>`, and every such expression should be
37+
/// measured separately.
38+
///
39+
/// In general, a `visit_foo` method should be implemented here if the
40+
/// corresponding `Foo` type is always stored on its own, e.g.: `P<Foo>`,
41+
/// `Box<Foo>`, `Vec<Foo>`, `Box<[Foo]>`.
42+
///
43+
/// There are some types in the AST and HIR tree that the visitors do not have
44+
/// a `visit_*` method for, and so we cannot measure these, which is
45+
/// unfortunate.
2946
struct StatCollector<'k> {
3047
krate: Option<Map<'k>>,
3148
data: FxHashMap<&'static str, NodeData>,
@@ -44,9 +61,11 @@ pub fn print_hir_stats(tcx: TyCtxt<'_>) {
4461
}
4562

4663
pub fn print_ast_stats(krate: &ast::Crate, title: &str) {
64+
use rustc_ast::visit::Visitor;
65+
4766
let mut collector =
4867
StatCollector { krate: None, data: FxHashMap::default(), seen: FxHashSet::default() };
49-
ast_visit::walk_crate(&mut collector, krate);
68+
collector.visit_crate(krate);
5069
collector.print(title);
5170
}
5271

@@ -228,6 +247,10 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
228247
hir_visit::walk_path(self, path)
229248
}
230249

250+
// `PathSegment` has one inline use (in `ast::ExprKind::MethodCall`) and
251+
// one non-inline use (in `Path::segments`). The latter case is more common
252+
// than the former case, so we implement this visitor and tolerate the
253+
// double counting in the former case.
231254
fn visit_path_segment(&mut self, path_span: Span, path_segment: &'v hir::PathSegment<'v>) {
232255
self.record("PathSegment", Id::None, path_segment);
233256
hir_visit::walk_path_segment(self, path_span, path_segment)
@@ -269,6 +292,11 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
269292
ast_visit::walk_stmt(self, s)
270293
}
271294

295+
fn visit_param(&mut self, p: &'v ast::Param) {
296+
self.record("Param", Id::None, p);
297+
ast_visit::walk_param(self, p)
298+
}
299+
272300
fn visit_arm(&mut self, a: &'v ast::Arm) {
273301
self.record("Arm", Id::None, a);
274302
ast_visit::walk_arm(self, a)
@@ -289,6 +317,16 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
289317
ast_visit::walk_ty(self, t)
290318
}
291319

320+
fn visit_generic_param(&mut self, g: &'v ast::GenericParam) {
321+
self.record("GenericParam", Id::None, g);
322+
ast_visit::walk_generic_param(self, g)
323+
}
324+
325+
fn visit_where_predicate(&mut self, p: &'v ast::WherePredicate) {
326+
self.record("WherePredicate", Id::None, p);
327+
ast_visit::walk_where_predicate(self, p)
328+
}
329+
292330
fn visit_fn(&mut self, fk: ast_visit::FnKind<'v>, s: Span, _: NodeId) {
293331
self.record("FnDecl", Id::None, fk.decl());
294332
ast_visit::walk_fn(self, fk, s)
@@ -318,27 +356,42 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
318356
ast_visit::walk_variant(self, v)
319357
}
320358

321-
fn visit_lifetime(&mut self, lifetime: &'v ast::Lifetime, _: ast_visit::LifetimeCtxt) {
322-
self.record("Lifetime", Id::None, lifetime);
323-
ast_visit::walk_lifetime(self, lifetime)
324-
}
325-
326-
fn visit_mac_call(&mut self, mac: &'v ast::MacCall) {
327-
self.record("MacCall", Id::None, mac);
328-
ast_visit::walk_mac(self, mac)
329-
}
359+
// `UseTree` has one inline use (in `ast::ItemKind::Use`) and one
360+
// non-inline use (in `ast::UseTreeKind::Nested). The former case is more
361+
// common, so we don't implement `visit_use_tree` and tolerate the missed
362+
// coverage in the latter case.
330363

331364
fn visit_path_segment(&mut self, path_span: Span, path_segment: &'v ast::PathSegment) {
332365
self.record("PathSegment", Id::None, path_segment);
333366
ast_visit::walk_path_segment(self, path_span, path_segment)
334367
}
335368

336-
fn visit_assoc_constraint(&mut self, constraint: &'v ast::AssocConstraint) {
337-
self.record("AssocConstraint", Id::None, constraint);
338-
ast_visit::walk_assoc_constraint(self, constraint)
369+
// `GenericArgs` has one inline use (in `ast::AssocConstraint::gen_args`) and one
370+
// non-inline use (in `ast::PathSegment::args`). The latter case is more
371+
// common, so we implement `visit_generic_args` and tolerate the double
372+
// counting in the former case.
373+
fn visit_generic_args(&mut self, sp: Span, g: &'v ast::GenericArgs) {
374+
self.record("GenericArgs", Id::None, g);
375+
ast_visit::walk_generic_args(self, sp, g)
339376
}
340377

341378
fn visit_attribute(&mut self, attr: &'v ast::Attribute) {
342379
self.record("Attribute", Id::None, attr);
380+
ast_visit::walk_attribute(self, attr)
381+
}
382+
383+
fn visit_expr_field(&mut self, f: &'v ast::ExprField) {
384+
self.record("ExprField", Id::None, f);
385+
ast_visit::walk_expr_field(self, f)
386+
}
387+
388+
fn visit_crate(&mut self, krate: &'v ast::Crate) {
389+
self.record("Crate", Id::None, krate);
390+
ast_visit::walk_crate(self, krate)
391+
}
392+
393+
fn visit_inline_asm(&mut self, asm: &'v ast::InlineAsm) {
394+
self.record("InlineAsm", Id::None, asm);
395+
ast_visit::walk_inline_asm(self, asm)
343396
}
344397
}

src/test/ui/stats/hir-stats.stderr

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,53 +3,63 @@ PRE EXPANSION AST STATS
33

44
Name Accumulated Size Count Item Size
55
----------------------------------------------------------------
6-
Lifetime 32 2 16
7-
MacCall 64 1 64
6+
ExprField 48 1 48
7+
GenericArgs 64 1 64
88
Local 72 1 72
9+
WherePredicate 72 1 72
10+
Crate 72 1 72
911
Arm 96 2 48
1012
FieldDef 160 2 80
1113
ForeignItem 160 1 160
1214
Stmt 160 5 32
15+
Param 160 4 40
1316
FnDecl 200 5 40
1417
Variant 240 2 120
1518
Block 288 6 48
1619
Attribute 304 2 152
1720
ImplItem 320 2 160
1821
TraitItem 320 2 160
1922
GenericBound 352 4 88
23+
GenericParam 520 5 104
2024
PathSegment 720 30 24
2125
Expr 832 8 104
2226
Pat 840 7 120
2327
Ty 1_344 14 96
2428
Item 1_800 9 200
2529
----------------------------------------------------------------
26-
Total 8_304
30+
Total 9_144
2731

2832

2933
POST EXPANSION AST STATS
3034

3135
Name Accumulated Size Count Item Size
3236
----------------------------------------------------------------
33-
Lifetime 32 2 16
37+
ExprField 48 1 48
38+
GenericArgs 64 1 64
3439
Local 72 1 72
40+
WherePredicate 72 1 72
41+
Crate 72 1 72
3542
Arm 96 2 48
43+
InlineAsm 120 1 120
3644
FieldDef 160 2 80
3745
ForeignItem 160 1 160
3846
Stmt 160 5 32
47+
Param 160 4 40
3948
FnDecl 200 5 40
4049
Variant 240 2 120
4150
Block 288 6 48
4251
ImplItem 320 2 160
4352
TraitItem 320 2 160
4453
GenericBound 352 4 88
54+
GenericParam 520 5 104
4555
Attribute 608 4 152
4656
PathSegment 792 33 24
4757
Pat 840 7 120
4858
Expr 936 9 104
4959
Ty 1_344 14 96
5060
Item 2_200 11 200
5161
----------------------------------------------------------------
52-
Total 9_120
62+
Total 10_144
5363

5464

5565
HIR STATS

0 commit comments

Comments
 (0)