Skip to content

Commit f7dc917

Browse files
committed
Add -Zinput-stats
Emits loc, and node count - before and after expansion. E.g., ``` rustc: x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore Lines of code: 32060 Pre-expansion node count: 120205 Post-expansion node count: 482749 ```
1 parent f1f5c04 commit f7dc917

File tree

5 files changed

+218
-26
lines changed

5 files changed

+218
-26
lines changed

src/librustc/session/config.rs

+27-25
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options,
510510
"debug info emission level, 0 = no debug info, 1 = line tables only, \
511511
2 = full debug info with variable and type information"),
512512
opt_level: Option<usize> = (None, parse_opt_uint,
513-
"Optimize with possible levels 0-3"),
513+
"optimize with possible levels 0-3"),
514514
debug_assertions: Option<bool> = (None, parse_opt_bool,
515515
"explicitly enable the cfg(debug_assertions) directive"),
516516
}
@@ -527,6 +527,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
527527
"count where LLVM instrs originate"),
528528
time_llvm_passes: bool = (false, parse_bool,
529529
"measure time of each LLVM pass"),
530+
input_stats: bool = (false, parse_bool,
531+
"gather statistics about the input"),
530532
trans_stats: bool = (false, parse_bool,
531533
"gather trans statistics"),
532534
asm_comments: bool = (false, parse_bool,
@@ -544,56 +546,56 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
544546
meta_stats: bool = (false, parse_bool,
545547
"gather metadata statistics"),
546548
print_link_args: bool = (false, parse_bool,
547-
"Print the arguments passed to the linker"),
549+
"print the arguments passed to the linker"),
548550
gc: bool = (false, parse_bool,
549-
"Garbage collect shared data (experimental)"),
551+
"garbage collect shared data (experimental)"),
550552
print_llvm_passes: bool = (false, parse_bool,
551-
"Prints the llvm optimization passes being run"),
553+
"prints the llvm optimization passes being run"),
552554
ast_json: bool = (false, parse_bool,
553-
"Print the AST as JSON and halt"),
555+
"print the AST as JSON and halt"),
554556
ast_json_noexpand: bool = (false, parse_bool,
555-
"Print the pre-expansion AST as JSON and halt"),
557+
"print the pre-expansion AST as JSON and halt"),
556558
ls: bool = (false, parse_bool,
557-
"List the symbols defined by a library crate"),
559+
"list the symbols defined by a library crate"),
558560
save_analysis: bool = (false, parse_bool,
559-
"Write syntax and type analysis information in addition to normal output"),
561+
"write syntax and type analysis information in addition to normal output"),
560562
print_move_fragments: bool = (false, parse_bool,
561-
"Print out move-fragment data for every fn"),
563+
"print out move-fragment data for every fn"),
562564
flowgraph_print_loans: bool = (false, parse_bool,
563-
"Include loan analysis data in --unpretty flowgraph output"),
565+
"include loan analysis data in --unpretty flowgraph output"),
564566
flowgraph_print_moves: bool = (false, parse_bool,
565-
"Include move analysis data in --unpretty flowgraph output"),
567+
"include move analysis data in --unpretty flowgraph output"),
566568
flowgraph_print_assigns: bool = (false, parse_bool,
567-
"Include assignment analysis data in --unpretty flowgraph output"),
569+
"include assignment analysis data in --unpretty flowgraph output"),
568570
flowgraph_print_all: bool = (false, parse_bool,
569-
"Include all dataflow analysis data in --unpretty flowgraph output"),
571+
"include all dataflow analysis data in --unpretty flowgraph output"),
570572
print_region_graph: bool = (false, parse_bool,
571-
"Prints region inference graph. \
573+
"prints region inference graph. \
572574
Use with RUST_REGION_GRAPH=help for more info"),
573575
parse_only: bool = (false, parse_bool,
574-
"Parse only; do not compile, assemble, or link"),
576+
"parse only; do not compile, assemble, or link"),
575577
no_trans: bool = (false, parse_bool,
576-
"Run all passes except translation; no output"),
578+
"run all passes except translation; no output"),
577579
treat_err_as_bug: bool = (false, parse_bool,
578-
"Treat all errors that occur as bugs"),
580+
"treat all errors that occur as bugs"),
579581
no_analysis: bool = (false, parse_bool,
580-
"Parse and expand the source, but run no analysis"),
582+
"parse and expand the source, but run no analysis"),
581583
extra_plugins: Vec<String> = (Vec::new(), parse_list,
582584
"load extra plugins"),
583585
unstable_options: bool = (false, parse_bool,
584-
"Adds unstable command line options to rustc interface"),
586+
"adds unstable command line options to rustc interface"),
585587
print_enum_sizes: bool = (false, parse_bool,
586-
"Print the size of enums and their variants"),
588+
"print the size of enums and their variants"),
587589
force_overflow_checks: Option<bool> = (None, parse_opt_bool,
588-
"Force overflow checks on or off"),
590+
"force overflow checks on or off"),
589591
force_dropflag_checks: Option<bool> = (None, parse_opt_bool,
590-
"Force drop flag checks on or off"),
592+
"force drop flag checks on or off"),
591593
trace_macros: bool = (false, parse_bool,
592-
"For every macro invocation, print its name and arguments"),
594+
"for every macro invocation, print its name and arguments"),
593595
enable_nonzeroing_move_hints: bool = (false, parse_bool,
594-
"Force nonzeroing move optimization on"),
596+
"force nonzeroing move optimization on"),
595597
keep_mtwt_tables: bool = (false, parse_bool,
596-
"Don't clear the resolution tables after analysis"),
598+
"don't clear the resolution tables after analysis"),
597599
}
598600

599601
pub fn default_lib_output() -> CrateType {

src/librustc_driver/driver.rs

+17
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ use syntax::feature_gate::UnstableFeatures;
5252
use syntax::fold::Folder;
5353
use syntax::parse;
5454
use syntax::parse::token;
55+
use syntax::util::node_count::NodeCounter;
56+
use syntax::visit;
5557
use syntax;
5658

5759
pub fn compile_input(sess: Session,
@@ -398,13 +400,24 @@ pub fn phase_1_parse_input(sess: &Session, cfg: ast::CrateConfig, input: &Input)
398400
println!("{}", json::as_json(&krate));
399401
}
400402

403+
if sess.opts.debugging_opts.input_stats {
404+
println!("Lines of code: {}", sess.codemap().count_lines());
405+
println!("Pre-expansion node count: {}", count_nodes(&krate));
406+
}
407+
401408
if let Some(ref s) = sess.opts.show_span {
402409
syntax::show_span::run(sess.diagnostic(), s, &krate);
403410
}
404411

405412
krate
406413
}
407414

415+
fn count_nodes(krate: &ast::Crate) -> usize {
416+
let mut counter = NodeCounter::new();
417+
visit::walk_crate(&mut counter, krate);
418+
counter.count
419+
}
420+
408421
// For continuing compilation after a parsed crate has been
409422
// modified
410423

@@ -606,6 +619,10 @@ pub fn phase_2_configure_and_expand(sess: &Session,
606619
sess.abort_if_errors();
607620
});
608621

622+
if sess.opts.debugging_opts.input_stats {
623+
println!("Post-expansion node count: {}", count_nodes(&krate));
624+
}
625+
609626
Some(krate)
610627
}
611628

src/libsyntax/codemap.rs

+8
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,10 @@ impl FileMap {
559559
pub fn is_imported(&self) -> bool {
560560
self.src.is_none()
561561
}
562+
563+
fn count_lines(&self) -> usize {
564+
self.lines.borrow().len()
565+
}
562566
}
563567

564568
/// An abstraction over the fs operations used by the Parser.
@@ -1021,6 +1025,10 @@ impl CodeMap {
10211025
debug!("span_allows_unstable? {}", allows_unstable);
10221026
allows_unstable
10231027
}
1028+
1029+
pub fn count_lines(&self) -> usize {
1030+
self.files.borrow().iter().fold(0, |a, f| a + f.count_lines())
1031+
}
10241032
}
10251033

10261034
// _____________________________________________________________________________

src/libsyntax/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,11 @@ macro_rules! panictry {
6262

6363
pub mod util {
6464
pub mod interner;
65+
pub mod node_count;
66+
pub mod parser;
6567
#[cfg(test)]
6668
pub mod parser_testing;
6769
pub mod small_vector;
68-
pub mod parser;
6970
}
7071

7172
pub mod diagnostics {

src/libsyntax/util/node_count.rs

+164
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Simply gives a rought count of the number of nodes in an AST.
12+
13+
use visit::*;
14+
use ast::*;
15+
use codemap::Span;
16+
17+
pub struct NodeCounter {
18+
pub count: usize,
19+
}
20+
21+
impl NodeCounter {
22+
pub fn new() -> NodeCounter {
23+
NodeCounter {
24+
count: 0,
25+
}
26+
}
27+
}
28+
29+
impl<'v> Visitor<'v> for NodeCounter {
30+
fn visit_ident(&mut self, span: Span, ident: Ident) {
31+
self.count += 1;
32+
walk_ident(self, span, ident);
33+
}
34+
fn visit_mod(&mut self, m: &'v Mod, _s: Span, _n: NodeId) {
35+
self.count += 1;
36+
walk_mod(self, m)
37+
}
38+
fn visit_foreign_item(&mut self, i: &'v ForeignItem) {
39+
self.count += 1;
40+
walk_foreign_item(self, i)
41+
}
42+
fn visit_item(&mut self, i: &'v Item) {
43+
self.count += 1;
44+
walk_item(self, i)
45+
}
46+
fn visit_local(&mut self, l: &'v Local) {
47+
self.count += 1;
48+
walk_local(self, l)
49+
}
50+
fn visit_block(&mut self, b: &'v Block) {
51+
self.count += 1;
52+
walk_block(self, b)
53+
}
54+
fn visit_stmt(&mut self, s: &'v Stmt) {
55+
self.count += 1;
56+
walk_stmt(self, s)
57+
}
58+
fn visit_arm(&mut self, a: &'v Arm) {
59+
self.count += 1;
60+
walk_arm(self, a)
61+
}
62+
fn visit_pat(&mut self, p: &'v Pat) {
63+
self.count += 1;
64+
walk_pat(self, p)
65+
}
66+
fn visit_decl(&mut self, d: &'v Decl) {
67+
self.count += 1;
68+
walk_decl(self, d)
69+
}
70+
fn visit_expr(&mut self, ex: &'v Expr) {
71+
self.count += 1;
72+
walk_expr(self, ex)
73+
}
74+
fn visit_ty(&mut self, t: &'v Ty) {
75+
self.count += 1;
76+
walk_ty(self, t)
77+
}
78+
fn visit_generics(&mut self, g: &'v Generics) {
79+
self.count += 1;
80+
walk_generics(self, g)
81+
}
82+
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: &'v Block, s: Span, _: NodeId) {
83+
self.count += 1;
84+
walk_fn(self, fk, fd, b, s)
85+
}
86+
fn visit_trait_item(&mut self, ti: &'v TraitItem) {
87+
self.count += 1;
88+
walk_trait_item(self, ti)
89+
}
90+
fn visit_impl_item(&mut self, ii: &'v ImplItem) {
91+
self.count += 1;
92+
walk_impl_item(self, ii)
93+
}
94+
fn visit_trait_ref(&mut self, t: &'v TraitRef) {
95+
self.count += 1;
96+
walk_trait_ref(self, t)
97+
}
98+
fn visit_ty_param_bound(&mut self, bounds: &'v TyParamBound) {
99+
self.count += 1;
100+
walk_ty_param_bound(self, bounds)
101+
}
102+
fn visit_poly_trait_ref(&mut self, t: &'v PolyTraitRef, m: &'v TraitBoundModifier) {
103+
self.count += 1;
104+
walk_poly_trait_ref(self, t, m)
105+
}
106+
fn visit_variant_data(&mut self, s: &'v VariantData, _: Ident,
107+
_: &'v Generics, _: NodeId, _: Span) {
108+
self.count += 1;
109+
walk_struct_def(self, s)
110+
}
111+
fn visit_struct_field(&mut self, s: &'v StructField) {
112+
self.count += 1;
113+
walk_struct_field(self, s)
114+
}
115+
fn visit_enum_def(&mut self, enum_definition: &'v EnumDef,
116+
generics: &'v Generics, item_id: NodeId, _: Span) {
117+
self.count += 1;
118+
walk_enum_def(self, enum_definition, generics, item_id)
119+
}
120+
fn visit_variant(&mut self, v: &'v Variant, g: &'v Generics, item_id: NodeId) {
121+
self.count += 1;
122+
walk_variant(self, v, g, item_id)
123+
}
124+
fn visit_lifetime(&mut self, lifetime: &'v Lifetime) {
125+
self.count += 1;
126+
walk_lifetime(self, lifetime)
127+
}
128+
fn visit_lifetime_def(&mut self, lifetime: &'v LifetimeDef) {
129+
self.count += 1;
130+
walk_lifetime_def(self, lifetime)
131+
}
132+
fn visit_explicit_self(&mut self, es: &'v ExplicitSelf) {
133+
self.count += 1;
134+
walk_explicit_self(self, es)
135+
}
136+
fn visit_mac(&mut self, _mac: &'v Mac) {
137+
self.count += 1;
138+
walk_mac(self, _mac)
139+
}
140+
fn visit_path(&mut self, path: &'v Path, _id: NodeId) {
141+
self.count += 1;
142+
walk_path(self, path)
143+
}
144+
fn visit_path_list_item(&mut self, prefix: &'v Path, item: &'v PathListItem) {
145+
self.count += 1;
146+
walk_path_list_item(self, prefix, item)
147+
}
148+
fn visit_path_parameters(&mut self, path_span: Span, path_parameters: &'v PathParameters) {
149+
self.count += 1;
150+
walk_path_parameters(self, path_span, path_parameters)
151+
}
152+
fn visit_assoc_type_binding(&mut self, type_binding: &'v TypeBinding) {
153+
self.count += 1;
154+
walk_assoc_type_binding(self, type_binding)
155+
}
156+
fn visit_attribute(&mut self, _attr: &'v Attribute) {
157+
self.count += 1;
158+
}
159+
fn visit_macro_def(&mut self, macro_def: &'v MacroDef) {
160+
self.count += 1;
161+
walk_macro_def(self, macro_def)
162+
}
163+
164+
}

0 commit comments

Comments
 (0)