Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add -Zinput-stats #29764

Merged
merged 1 commit into from
Nov 12, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 27 additions & 25 deletions src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,7 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options,
"debug info emission level, 0 = no debug info, 1 = line tables only, \
2 = full debug info with variable and type information"),
opt_level: Option<usize> = (None, parse_opt_uint,
"Optimize with possible levels 0-3"),
"optimize with possible levels 0-3"),
debug_assertions: Option<bool> = (None, parse_opt_bool,
"explicitly enable the cfg(debug_assertions) directive"),
}
Expand All @@ -527,6 +527,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
"count where LLVM instrs originate"),
time_llvm_passes: bool = (false, parse_bool,
"measure time of each LLVM pass"),
input_stats: bool = (false, parse_bool,
"gather statistics about the input"),
trans_stats: bool = (false, parse_bool,
"gather trans statistics"),
asm_comments: bool = (false, parse_bool,
Expand All @@ -544,56 +546,56 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
meta_stats: bool = (false, parse_bool,
"gather metadata statistics"),
print_link_args: bool = (false, parse_bool,
"Print the arguments passed to the linker"),
"print the arguments passed to the linker"),
gc: bool = (false, parse_bool,
"Garbage collect shared data (experimental)"),
"garbage collect shared data (experimental)"),
print_llvm_passes: bool = (false, parse_bool,
"Prints the llvm optimization passes being run"),
"prints the llvm optimization passes being run"),
ast_json: bool = (false, parse_bool,
"Print the AST as JSON and halt"),
"print the AST as JSON and halt"),
ast_json_noexpand: bool = (false, parse_bool,
"Print the pre-expansion AST as JSON and halt"),
"print the pre-expansion AST as JSON and halt"),
ls: bool = (false, parse_bool,
"List the symbols defined by a library crate"),
"list the symbols defined by a library crate"),
save_analysis: bool = (false, parse_bool,
"Write syntax and type analysis information in addition to normal output"),
"write syntax and type analysis information in addition to normal output"),
print_move_fragments: bool = (false, parse_bool,
"Print out move-fragment data for every fn"),
"print out move-fragment data for every fn"),
flowgraph_print_loans: bool = (false, parse_bool,
"Include loan analysis data in --unpretty flowgraph output"),
"include loan analysis data in --unpretty flowgraph output"),
flowgraph_print_moves: bool = (false, parse_bool,
"Include move analysis data in --unpretty flowgraph output"),
"include move analysis data in --unpretty flowgraph output"),
flowgraph_print_assigns: bool = (false, parse_bool,
"Include assignment analysis data in --unpretty flowgraph output"),
"include assignment analysis data in --unpretty flowgraph output"),
flowgraph_print_all: bool = (false, parse_bool,
"Include all dataflow analysis data in --unpretty flowgraph output"),
"include all dataflow analysis data in --unpretty flowgraph output"),
print_region_graph: bool = (false, parse_bool,
"Prints region inference graph. \
"prints region inference graph. \
Use with RUST_REGION_GRAPH=help for more info"),
parse_only: bool = (false, parse_bool,
"Parse only; do not compile, assemble, or link"),
"parse only; do not compile, assemble, or link"),
no_trans: bool = (false, parse_bool,
"Run all passes except translation; no output"),
"run all passes except translation; no output"),
treat_err_as_bug: bool = (false, parse_bool,
"Treat all errors that occur as bugs"),
"treat all errors that occur as bugs"),
no_analysis: bool = (false, parse_bool,
"Parse and expand the source, but run no analysis"),
"parse and expand the source, but run no analysis"),
extra_plugins: Vec<String> = (Vec::new(), parse_list,
"load extra plugins"),
unstable_options: bool = (false, parse_bool,
"Adds unstable command line options to rustc interface"),
"adds unstable command line options to rustc interface"),
print_enum_sizes: bool = (false, parse_bool,
"Print the size of enums and their variants"),
"print the size of enums and their variants"),
force_overflow_checks: Option<bool> = (None, parse_opt_bool,
"Force overflow checks on or off"),
"force overflow checks on or off"),
force_dropflag_checks: Option<bool> = (None, parse_opt_bool,
"Force drop flag checks on or off"),
"force drop flag checks on or off"),
trace_macros: bool = (false, parse_bool,
"For every macro invocation, print its name and arguments"),
"for every macro invocation, print its name and arguments"),
enable_nonzeroing_move_hints: bool = (false, parse_bool,
"Force nonzeroing move optimization on"),
"force nonzeroing move optimization on"),
keep_mtwt_tables: bool = (false, parse_bool,
"Don't clear the resolution tables after analysis"),
"don't clear the resolution tables after analysis"),
}

pub fn default_lib_output() -> CrateType {
Expand Down
17 changes: 17 additions & 0 deletions src/librustc_driver/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ use syntax::feature_gate::UnstableFeatures;
use syntax::fold::Folder;
use syntax::parse;
use syntax::parse::token;
use syntax::util::node_count::NodeCounter;
use syntax::visit;
use syntax;

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

if sess.opts.debugging_opts.input_stats {
println!("Lines of code: {}", sess.codemap().count_lines());
println!("Pre-expansion node count: {}", count_nodes(&krate));
}

if let Some(ref s) = sess.opts.show_span {
syntax::show_span::run(sess.diagnostic(), s, &krate);
}

krate
}

fn count_nodes(krate: &ast::Crate) -> usize {
let mut counter = NodeCounter::new();
visit::walk_crate(&mut counter, krate);
counter.count
}

// For continuing compilation after a parsed crate has been
// modified

Expand Down Expand Up @@ -606,6 +619,10 @@ pub fn phase_2_configure_and_expand(sess: &Session,
sess.abort_if_errors();
});

if sess.opts.debugging_opts.input_stats {
println!("Post-expansion node count: {}", count_nodes(&krate));
}

Some(krate)
}

Expand Down
8 changes: 8 additions & 0 deletions src/libsyntax/codemap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,10 @@ impl FileMap {
pub fn is_imported(&self) -> bool {
self.src.is_none()
}

fn count_lines(&self) -> usize {
self.lines.borrow().len()
}
}

/// An abstraction over the fs operations used by the Parser.
Expand Down Expand Up @@ -1021,6 +1025,10 @@ impl CodeMap {
debug!("span_allows_unstable? {}", allows_unstable);
allows_unstable
}

pub fn count_lines(&self) -> usize {
self.files.borrow().iter().fold(0, |a, f| a + f.count_lines())
}
}

// _____________________________________________________________________________
Expand Down
3 changes: 2 additions & 1 deletion src/libsyntax/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,11 @@ macro_rules! panictry {

pub mod util {
pub mod interner;
pub mod node_count;
pub mod parser;
#[cfg(test)]
pub mod parser_testing;
pub mod small_vector;
pub mod parser;
}

pub mod diagnostics {
Expand Down
164 changes: 164 additions & 0 deletions src/libsyntax/util/node_count.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// Simply gives a rought count of the number of nodes in an AST.

use visit::*;
use ast::*;
use codemap::Span;

pub struct NodeCounter {
pub count: usize,
}

impl NodeCounter {
pub fn new() -> NodeCounter {
NodeCounter {
count: 0,
}
}
}

impl<'v> Visitor<'v> for NodeCounter {
fn visit_ident(&mut self, span: Span, ident: Ident) {
self.count += 1;
walk_ident(self, span, ident);
}
fn visit_mod(&mut self, m: &'v Mod, _s: Span, _n: NodeId) {
self.count += 1;
walk_mod(self, m)
}
fn visit_foreign_item(&mut self, i: &'v ForeignItem) {
self.count += 1;
walk_foreign_item(self, i)
}
fn visit_item(&mut self, i: &'v Item) {
self.count += 1;
walk_item(self, i)
}
fn visit_local(&mut self, l: &'v Local) {
self.count += 1;
walk_local(self, l)
}
fn visit_block(&mut self, b: &'v Block) {
self.count += 1;
walk_block(self, b)
}
fn visit_stmt(&mut self, s: &'v Stmt) {
self.count += 1;
walk_stmt(self, s)
}
fn visit_arm(&mut self, a: &'v Arm) {
self.count += 1;
walk_arm(self, a)
}
fn visit_pat(&mut self, p: &'v Pat) {
self.count += 1;
walk_pat(self, p)
}
fn visit_decl(&mut self, d: &'v Decl) {
self.count += 1;
walk_decl(self, d)
}
fn visit_expr(&mut self, ex: &'v Expr) {
self.count += 1;
walk_expr(self, ex)
}
fn visit_ty(&mut self, t: &'v Ty) {
self.count += 1;
walk_ty(self, t)
}
fn visit_generics(&mut self, g: &'v Generics) {
self.count += 1;
walk_generics(self, g)
}
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: &'v Block, s: Span, _: NodeId) {
self.count += 1;
walk_fn(self, fk, fd, b, s)
}
fn visit_trait_item(&mut self, ti: &'v TraitItem) {
self.count += 1;
walk_trait_item(self, ti)
}
fn visit_impl_item(&mut self, ii: &'v ImplItem) {
self.count += 1;
walk_impl_item(self, ii)
}
fn visit_trait_ref(&mut self, t: &'v TraitRef) {
self.count += 1;
walk_trait_ref(self, t)
}
fn visit_ty_param_bound(&mut self, bounds: &'v TyParamBound) {
self.count += 1;
walk_ty_param_bound(self, bounds)
}
fn visit_poly_trait_ref(&mut self, t: &'v PolyTraitRef, m: &'v TraitBoundModifier) {
self.count += 1;
walk_poly_trait_ref(self, t, m)
}
fn visit_variant_data(&mut self, s: &'v VariantData, _: Ident,
_: &'v Generics, _: NodeId, _: Span) {
self.count += 1;
walk_struct_def(self, s)
}
fn visit_struct_field(&mut self, s: &'v StructField) {
self.count += 1;
walk_struct_field(self, s)
}
fn visit_enum_def(&mut self, enum_definition: &'v EnumDef,
generics: &'v Generics, item_id: NodeId, _: Span) {
self.count += 1;
walk_enum_def(self, enum_definition, generics, item_id)
}
fn visit_variant(&mut self, v: &'v Variant, g: &'v Generics, item_id: NodeId) {
self.count += 1;
walk_variant(self, v, g, item_id)
}
fn visit_lifetime(&mut self, lifetime: &'v Lifetime) {
self.count += 1;
walk_lifetime(self, lifetime)
}
fn visit_lifetime_def(&mut self, lifetime: &'v LifetimeDef) {
self.count += 1;
walk_lifetime_def(self, lifetime)
}
fn visit_explicit_self(&mut self, es: &'v ExplicitSelf) {
self.count += 1;
walk_explicit_self(self, es)
}
fn visit_mac(&mut self, _mac: &'v Mac) {
self.count += 1;
walk_mac(self, _mac)
}
fn visit_path(&mut self, path: &'v Path, _id: NodeId) {
self.count += 1;
walk_path(self, path)
}
fn visit_path_list_item(&mut self, prefix: &'v Path, item: &'v PathListItem) {
self.count += 1;
walk_path_list_item(self, prefix, item)
}
fn visit_path_parameters(&mut self, path_span: Span, path_parameters: &'v PathParameters) {
self.count += 1;
walk_path_parameters(self, path_span, path_parameters)
}
fn visit_assoc_type_binding(&mut self, type_binding: &'v TypeBinding) {
self.count += 1;
walk_assoc_type_binding(self, type_binding)
}
fn visit_attribute(&mut self, _attr: &'v Attribute) {
self.count += 1;
}
fn visit_macro_def(&mut self, macro_def: &'v MacroDef) {
self.count += 1;
walk_macro_def(self, macro_def)
}

}