From 7488502161dc546ef187c767de2fd9d65189c612 Mon Sep 17 00:00:00 2001 From: Julian Wollersberger Date: Sat, 3 Oct 2020 10:25:32 +0200 Subject: [PATCH 01/10] Added a --files option to analyse rustc's --emit=llvm-lines output. --- Cargo.toml | 1 + src/main.rs | 55 ++++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 47 insertions(+), 9 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ff3ed40..f2b68de 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,7 @@ rustc-demangle = "0.1" tempdir = "0.3" structopt = "0.3.8" clap = { version = "2.32.0", features = ["wrap_help"] } +glob = "0.3.0" [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] diff --git a/src/main.rs b/src/main.rs index fb2b412..9559301 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,6 +17,7 @@ use std::process::{self, Command, Stdio}; use std::str::FromStr; use structopt::StructOpt; use tempdir::TempDir; +use glob::glob; const ABOUT: &str = " Print amount of lines of LLVM IR that is generated for the current project. @@ -50,6 +51,17 @@ enum Opt { )] sort: SortOrder, + /// Analyze .ll files that were produced by eg. `RUSTFLAGS="--emit=llvm-ir" ./x.py build --stage 0 compiler/rustc`. + /// Supports globs, eg `./build/x86_64-unknown-linux-gnu/stage0-rustc/x86_64-unknown-linux-gnu/debug/deps/*.ll` + // zsh substitutes the glob with a list of files, therefore this needs to be a Vec. + #[structopt(short, long, value_name = "FILES")] + files: Vec, + + // Run in a different mode that just filters some Cargo output and does + // nothing else. + #[structopt(long, hidden = true)] + filter_cargo: bool, + // All these options are passed through to the `rustc` invocation. #[structopt(short, long, value_name = "SPEC")] package: Option, @@ -71,20 +83,28 @@ enum Opt { no_default_features: bool, #[structopt(long, value_name = "PATH")] manifest_path: Option, - - // Run in a different mode that just filters some Cargo output and does - // nothing else. - #[structopt(long, hidden = true)] - filter_cargo: bool, }, } fn main() { let Opt::LLVMLines { - filter_cargo, sort, .. + filter_cargo, sort, files, .. } = Opt::from_args(); - let result = cargo_llvm_lines(filter_cargo, sort); + let result = if files.len() > 0 { + // read llvm-lines from files + let content = read_llvm_ir_from_glob(&files); + match content { + Ok(ir) => { + count_lines(ir, sort); + Ok(0) + }, + Err(err) => Err(err) + } + } else { + // run cargo to get llvm-lines + cargo_llvm_lines(filter_cargo, sort) + }; process::exit(match result { Ok(code) => code, @@ -110,7 +130,7 @@ fn cargo_llvm_lines(filter_cargo: bool, sort_order: SortOrder) -> io::Result io::Result { child.wait().map(|status| status.code().unwrap_or(1)) } -fn read_llvm_ir(outdir: TempDir) -> io::Result { +fn read_llvm_ir_from_dir(outdir: TempDir) -> io::Result { for file in fs::read_dir(&outdir)? { let path = file?.path(); if let Some(ext) = path.extension() { @@ -173,6 +193,23 @@ fn read_llvm_ir(outdir: TempDir) -> io::Result { Err(io::Error::new(ErrorKind::Other, msg)) } +fn read_llvm_ir_from_glob(globs: &Vec) -> io::Result { + // This loads all files into RAM (4.1GB in the case of rustc), + // but it only takes seconds, so no need to optimize that. + let mut content = String::new(); + for file_glob in globs { + for entry in glob(file_glob).expect(&format!("Failed to read glob pattern '{}'", file_glob)) { + let path = entry.map_err(|err| io::Error::new(ErrorKind::Other, err))?; + if let Some(ext) = path.extension() { + if ext == "ll" { + File::open(&path)?.read_to_string(&mut content)?; + } + } + } + } + Ok(content) +} + #[derive(Default)] struct Instantiations { copies: usize, From 5453c7d7584aff5fe4d49db3779de193241ef209 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 3 Oct 2020 11:19:23 -0700 Subject: [PATCH 02/10] Format PR 32 with rustfmt --- src/main.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index 9559301..86e2a83 100644 --- a/src/main.rs +++ b/src/main.rs @@ -88,7 +88,10 @@ enum Opt { fn main() { let Opt::LLVMLines { - filter_cargo, sort, files, .. + filter_cargo, + sort, + files, + .. } = Opt::from_args(); let result = if files.len() > 0 { @@ -98,8 +101,8 @@ fn main() { Ok(ir) => { count_lines(ir, sort); Ok(0) - }, - Err(err) => Err(err) + } + Err(err) => Err(err), } } else { // run cargo to get llvm-lines From ae539fc4969d924761702f265fde257912b0852a Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 3 Oct 2020 11:12:50 -0700 Subject: [PATCH 03/10] Abbreviate --files help text The rustc dev guide will cover this workflow in more detail. --- src/main.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index 86e2a83..906d6c0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -51,9 +51,8 @@ enum Opt { )] sort: SortOrder, - /// Analyze .ll files that were produced by eg. `RUSTFLAGS="--emit=llvm-ir" ./x.py build --stage 0 compiler/rustc`. - /// Supports globs, eg `./build/x86_64-unknown-linux-gnu/stage0-rustc/x86_64-unknown-linux-gnu/debug/deps/*.ll` - // zsh substitutes the glob with a list of files, therefore this needs to be a Vec. + /// Analyze existing .ll files that were produced by e.g. + /// `RUSTFLAGS="--emit=llvm-ir" ./x.py build --stage 0 compiler/rustc`. #[structopt(short, long, value_name = "FILES")] files: Vec, From 5540160f15528ba63d793e13eb561a020538d734 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 3 Oct 2020 11:18:35 -0700 Subject: [PATCH 04/10] Drop glob dependency The shell will expand `--files ./build/debug/deps/*.ll`. --- Cargo.toml | 1 - src/main.rs | 16 ++++++---------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f2b68de..ff3ed40 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,6 @@ rustc-demangle = "0.1" tempdir = "0.3" structopt = "0.3.8" clap = { version = "2.32.0", features = ["wrap_help"] } -glob = "0.3.0" [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] diff --git a/src/main.rs b/src/main.rs index 906d6c0..fa18f2f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,7 +17,6 @@ use std::process::{self, Command, Stdio}; use std::str::FromStr; use structopt::StructOpt; use tempdir::TempDir; -use glob::glob; const ABOUT: &str = " Print amount of lines of LLVM IR that is generated for the current project. @@ -95,7 +94,7 @@ fn main() { let result = if files.len() > 0 { // read llvm-lines from files - let content = read_llvm_ir_from_glob(&files); + let content = read_llvm_ir_from_paths(&files); match content { Ok(ir) => { count_lines(ir, sort); @@ -195,17 +194,14 @@ fn read_llvm_ir_from_dir(outdir: TempDir) -> io::Result { Err(io::Error::new(ErrorKind::Other, msg)) } -fn read_llvm_ir_from_glob(globs: &Vec) -> io::Result { +fn read_llvm_ir_from_paths(paths: &Vec) -> io::Result { // This loads all files into RAM (4.1GB in the case of rustc), // but it only takes seconds, so no need to optimize that. let mut content = String::new(); - for file_glob in globs { - for entry in glob(file_glob).expect(&format!("Failed to read glob pattern '{}'", file_glob)) { - let path = entry.map_err(|err| io::Error::new(ErrorKind::Other, err))?; - if let Some(ext) = path.extension() { - if ext == "ll" { - File::open(&path)?.read_to_string(&mut content)?; - } + for path in paths { + if let Some(ext) = Path::new(&path).extension() { + if ext == "ll" { + File::open(&path)?.read_to_string(&mut content)?; } } } From 6c9a9e2f12aa80f22a8155741c0b4e2bf737c3bc Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 3 Oct 2020 11:22:50 -0700 Subject: [PATCH 05/10] Take --files arguments as PathBuf --- src/main.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index fa18f2f..871b986 100644 --- a/src/main.rs +++ b/src/main.rs @@ -53,7 +53,7 @@ enum Opt { /// Analyze existing .ll files that were produced by e.g. /// `RUSTFLAGS="--emit=llvm-ir" ./x.py build --stage 0 compiler/rustc`. #[structopt(short, long, value_name = "FILES")] - files: Vec, + files: Vec, // Run in a different mode that just filters some Cargo output and does // nothing else. @@ -194,12 +194,12 @@ fn read_llvm_ir_from_dir(outdir: TempDir) -> io::Result { Err(io::Error::new(ErrorKind::Other, msg)) } -fn read_llvm_ir_from_paths(paths: &Vec) -> io::Result { +fn read_llvm_ir_from_paths(paths: &Vec) -> io::Result { // This loads all files into RAM (4.1GB in the case of rustc), // but it only takes seconds, so no need to optimize that. let mut content = String::new(); for path in paths { - if let Some(ext) = Path::new(&path).extension() { + if let Some(ext) = path.extension() { if ext == "ll" { File::open(&path)?.read_to_string(&mut content)?; } From ac8737d501480b59f10cbdfad3cd3c62a6c29b6c Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 3 Oct 2020 11:27:49 -0700 Subject: [PATCH 06/10] Accept non-utf8 file path in --files --- src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index 871b986..2a5a87e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -52,7 +52,7 @@ enum Opt { /// Analyze existing .ll files that were produced by e.g. /// `RUSTFLAGS="--emit=llvm-ir" ./x.py build --stage 0 compiler/rustc`. - #[structopt(short, long, value_name = "FILES")] + #[structopt(short, long, value_name = "FILES", parse(from_os_str))] files: Vec, // Run in a different mode that just filters some Cargo output and does From 0faa4b39c4f1f6c9abcee9c7fa7cd7480212e41e Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 3 Oct 2020 11:51:42 -0700 Subject: [PATCH 07/10] Take all files passed to --files regardless of extension --- src/main.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main.rs b/src/main.rs index 2a5a87e..f411109 100644 --- a/src/main.rs +++ b/src/main.rs @@ -199,11 +199,7 @@ fn read_llvm_ir_from_paths(paths: &Vec) -> io::Result { // but it only takes seconds, so no need to optimize that. let mut content = String::new(); for path in paths { - if let Some(ext) = path.extension() { - if ext == "ll" { - File::open(&path)?.read_to_string(&mut content)?; - } - } + File::open(&path)?.read_to_string(&mut content)?; } Ok(content) } From fcf5da440c02eb72347b012e5e505c384a680426 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 3 Oct 2020 11:52:36 -0700 Subject: [PATCH 08/10] Resolve clippy len_zero lint --- src/main.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main.rs b/src/main.rs index f411109..bd7e801 100644 --- a/src/main.rs +++ b/src/main.rs @@ -92,7 +92,10 @@ fn main() { .. } = Opt::from_args(); - let result = if files.len() > 0 { + let result = if files.is_empty() { + // run cargo to get llvm-lines + cargo_llvm_lines(filter_cargo, sort) + } else { // read llvm-lines from files let content = read_llvm_ir_from_paths(&files); match content { @@ -102,9 +105,6 @@ fn main() { } Err(err) => Err(err), } - } else { - // run cargo to get llvm-lines - cargo_llvm_lines(filter_cargo, sort) }; process::exit(match result { From 8f481d62b3377bedec07f0416d184d88c8a36b17 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 3 Oct 2020 11:54:17 -0700 Subject: [PATCH 09/10] Resolve clippy ptr_arg lint --- src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index bd7e801..de87bdb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -194,7 +194,7 @@ fn read_llvm_ir_from_dir(outdir: TempDir) -> io::Result { Err(io::Error::new(ErrorKind::Other, msg)) } -fn read_llvm_ir_from_paths(paths: &Vec) -> io::Result { +fn read_llvm_ir_from_paths(paths: &[PathBuf]) -> io::Result { // This loads all files into RAM (4.1GB in the case of rustc), // but it only takes seconds, so no need to optimize that. let mut content = String::new(); From 379890973abbf4f70d9b7b828b8f9247481cb7a2 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 3 Oct 2020 11:58:47 -0700 Subject: [PATCH 10/10] Condense reading from paths codepath --- src/main.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/main.rs b/src/main.rs index de87bdb..8da49d5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -97,14 +97,10 @@ fn main() { cargo_llvm_lines(filter_cargo, sort) } else { // read llvm-lines from files - let content = read_llvm_ir_from_paths(&files); - match content { - Ok(ir) => { - count_lines(ir, sort); - Ok(0) - } - Err(err) => Err(err), - } + read_llvm_ir_from_paths(&files).map(|ir| { + count_lines(ir, sort); + 0 + }) }; process::exit(match result {