diff options
| author | Aman Arora <me@aman-arora.com> | 2021-05-05 15:57:08 -0400 |
|---|---|---|
| committer | Aman Arora <me@aman-arora.com> | 2021-06-28 14:21:55 -0400 |
| commit | fc273e9bf2ab4594e8dcdb737b63bffb3f6b08c9 (patch) | |
| tree | 5d4c81800d048385b8b3d24b8f70bad4ad03bdae /compiler/rustc_mir | |
| parent | 3e9d7ecf784e5ecaf7437d04be3992ad23fa7cb6 (diff) | |
| download | rust-fc273e9bf2ab4594e8dcdb737b63bffb3f6b08c9.tar.gz rust-fc273e9bf2ab4594e8dcdb737b63bffb3f6b08c9.zip | |
Introduce -Zprofile-closures to evaluate the impact of 2229
This creates a CSV with name "closure_profile_XXXXX.csv", where the variable part is the process id of the compiler. To profile a cargo project you can run one of the following depending on if you're compiling a library or a binary: ``` cargo +stage1 rustc --lib -- -Zprofile-closures cargo +stage1 rustc --bin -- -Zprofile-closures ```
Diffstat (limited to 'compiler/rustc_mir')
| -rw-r--r-- | compiler/rustc_mir/src/monomorphize/collector.rs | 7 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/monomorphize/mod.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/monomorphize/util.rs | 73 |
3 files changed, 81 insertions, 0 deletions
diff --git a/compiler/rustc_mir/src/monomorphize/collector.rs b/compiler/rustc_mir/src/monomorphize/collector.rs index 0ab9aa8e1bf..4bd431dcc6a 100644 --- a/compiler/rustc_mir/src/monomorphize/collector.rs +++ b/compiler/rustc_mir/src/monomorphize/collector.rs @@ -1071,6 +1071,13 @@ fn create_fn_mono_item<'tcx>( source: Span, ) -> Spanned<MonoItem<'tcx>> { debug!("create_fn_mono_item(instance={})", instance); + + let def_id = instance.def_id(); + if tcx.sess.opts.debugging_opts.profile_closures && def_id.is_local() && tcx.is_closure(def_id) + { + monomorphize::util::dump_closure_profile(tcx, instance); + } + respan(source, MonoItem::Fn(instance.polymorphize(tcx))) } diff --git a/compiler/rustc_mir/src/monomorphize/mod.rs b/compiler/rustc_mir/src/monomorphize/mod.rs index 9ca4b6687f1..57d2723cf9c 100644 --- a/compiler/rustc_mir/src/monomorphize/mod.rs +++ b/compiler/rustc_mir/src/monomorphize/mod.rs @@ -7,6 +7,7 @@ use rustc_hir::lang_items::LangItem; pub mod collector; pub mod partitioning; pub mod polymorphize; +pub mod util; fn custom_coerce_unsize_info<'tcx>( tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_mir/src/monomorphize/util.rs b/compiler/rustc_mir/src/monomorphize/util.rs new file mode 100644 index 00000000000..799b4e18c24 --- /dev/null +++ b/compiler/rustc_mir/src/monomorphize/util.rs @@ -0,0 +1,73 @@ +use rustc_middle::ty::{self, ClosureSizeProfileData, Instance, TyCtxt}; +use std::fs::OpenOptions; +use std::io::prelude::*; + +/// For a given closure, writes out the data for the profiling the impact of RFC 2229 on +/// closure size into a CSV. +/// +/// During the same compile all closures dump the information in the same file +/// "closure_profile_XXXXX.csv", which is created in the directory where the compiler is invoked. +crate fn dump_closure_profile(tcx: TyCtxt<'tcx>, closure_instance: Instance<'tcx>) { + let mut file = if let Ok(file) = OpenOptions::new() + .create(true) + .append(true) + .open(&format!("closure_profile_{}.csv", std::process::id())) + { + file + } else { + eprintln!("Cound't open file for writing closure profile"); + return; + }; + + let closure_def_id = closure_instance.def_id(); + let typeck_results = tcx.typeck(closure_def_id.expect_local()); + + if typeck_results.closure_size_eval.contains_key(&closure_def_id) { + let param_env = ty::ParamEnv::reveal_all(); + + let ClosureSizeProfileData { before_feature_tys, after_feature_tys } = + typeck_results.closure_size_eval[&closure_def_id]; + + let before_feature_tys = tcx.subst_and_normalize_erasing_regions( + closure_instance.substs, + param_env, + before_feature_tys, + ); + let after_feature_tys = tcx.subst_and_normalize_erasing_regions( + closure_instance.substs, + param_env, + after_feature_tys, + ); + + let new_size = tcx + .layout_of(param_env.and(after_feature_tys)) + .map(|l| format!("{:?}", l.size.bytes())) + .unwrap_or_else(|e| format!("Failed {:?}", e)); + + let old_size = tcx + .layout_of(param_env.and(before_feature_tys)) + .map(|l| format!("{:?}", l.size.bytes())) + .unwrap_or_else(|e| format!("Failed {:?}", e)); + + let closure_hir_id = tcx.hir().local_def_id_to_hir_id(closure_def_id.expect_local()); + let closure_span = tcx.hir().span(closure_hir_id); + let src_file = tcx.sess.source_map().span_to_filename(closure_span); + let line_nos = tcx + .sess + .source_map() + .span_to_lines(closure_span) + .map(|l| format!("{:?} {:?}", l.lines.first(), l.lines.last())) + .unwrap_or_else(|e| format!("{:?}", e)); + + if let Err(e) = writeln!( + file, + "{}, {}, {}, {:?}", + old_size, + new_size, + src_file.prefer_local(), + line_nos + ) { + eprintln!("Error writting to file {}", e.to_string()) + } + } +} |
