Auto merge of #56090 - nnethercote:filesearch, r=eddyb

Overhaul `FileSearch` and `SearchPaths`

`FileSearch::search()` traverses one or more directories. For each
directory it generates a `Vec<PathBuf>` containing one element per file
in that directory.

In some benchmarks this occurs enough that the allocations done for the
`PathBuf`s are significant, and in practice a small number of
directories are being traversed over and over again. For example, when
compiling the `tokio-webpush-simple` benchmark, two directories are
traversed 58 times each. Each of these directories have more than 100
files.

We can do all the necessary traversals up front, when `Session` is created,
and get the `Vec<PathBuf>`s then.

This reduces instruction counts on several benchmarks by 1--5%.

r? @alexcrichton

CC @eddyb, @michaelwoerister, @nikomatsakis
This commit is contained in:
bors 2018-12-13 03:35:15 +00:00
commit ced7cc5c65
13 changed files with 139 additions and 154 deletions

View file

@ -212,12 +212,7 @@ fn link_binary_output(sess: &Session,
}
fn archive_search_paths(sess: &Session) -> Vec<PathBuf> {
let mut search = Vec::new();
sess.target_filesearch(PathKind::Native).for_each_lib_search_path(|path, _| {
search.push(path.to_path_buf());
});
search
sess.target_filesearch(PathKind::Native).search_path_dirs()
}
fn archive_config<'a>(sess: &'a Session,
@ -1024,11 +1019,10 @@ fn link_args(cmd: &mut dyn Linker,
// where extern libraries might live, based on the
// addl_lib_search_paths
if sess.opts.cg.rpath {
let sysroot = sess.sysroot();
let target_triple = sess.opts.target_triple.triple();
let mut get_install_prefix_lib_path = || {
let install_prefix = option_env!("CFG_PREFIX").expect("CFG_PREFIX");
let tlib = filesearch::relative_target_lib_path(sysroot, target_triple);
let tlib = filesearch::relative_target_lib_path(&sess.sysroot, target_triple);
let mut path = PathBuf::from(install_prefix);
path.push(&tlib);
@ -1068,12 +1062,13 @@ fn link_args(cmd: &mut dyn Linker,
fn add_local_native_libraries(cmd: &mut dyn Linker,
sess: &Session,
codegen_results: &CodegenResults) {
sess.target_filesearch(PathKind::All).for_each_lib_search_path(|path, k| {
match k {
PathKind::Framework => { cmd.framework_path(path); }
_ => { cmd.include_path(&fix_windows_verbatim_for_gcc(path)); }
let filesearch = sess.target_filesearch(PathKind::All);
for search_path in filesearch.search_paths() {
match search_path.kind {
PathKind::Framework => { cmd.framework_path(&search_path.dir); }
_ => { cmd.include_path(&fix_windows_verbatim_for_gcc(&search_path.dir)); }
}
});
}
let relevant_libs = codegen_results.crate_info.used_libraries.iter().filter(|l| {
relevant_lib(sess, l)